Skip to content

Commit 9c3fb7a

Browse files
authored
Sync/4.6.1 (#10)
1 parent 888c272 commit 9c3fb7a

18 files changed

Lines changed: 391 additions & 266 deletions

.github/workflows/tests.yml

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
name: Tests
22
on:
33
workflow_dispatch:
4+
inputs:
5+
couchbase-server-version:
6+
description: 'Couchbase Server version to test against'
7+
type: choice
8+
required: false
9+
default: 'all'
10+
options:
11+
- 'all'
12+
- 'enterprise-7.2.4'
13+
- 'enterprise-7.6.4'
14+
- 'enterprise-8.0.0'
415
push:
516
branches:
617
- main
@@ -10,8 +21,8 @@ on:
1021
jobs:
1122
test:
1223
if: >
13-
(github.event_name == 'push'
14-
&& !contains(github.event.head_commit.message, 'skip ci')
24+
(github.event_name == 'push'
25+
&& !contains(github.event.head_commit.message, 'skip ci')
1526
&& !startsWith(github.event.head_commit.message, 'docs')) ||
1627
(github.event.issue.pull_request && startsWith(github.event.comment.body, '/test') && github.actor == 'JesusTheHun') ||
1728
github.event_name == 'workflow_dispatch'
@@ -21,7 +32,7 @@ jobs:
2132
strategy:
2233
fail-fast: false
2334
matrix:
24-
couchbase-server-version: [ 'enterprise-7.2.4', 'enterprise-7.6.4', 'enterprise-8.0.0' ]
35+
couchbase-server-version: ${{ github.event_name == 'workflow_dispatch' && inputs.couchbase-server-version != 'all' && fromJSON(format('["{0}"]', inputs.couchbase-server-version)) || fromJSON('["enterprise-7.2.4","enterprise-7.6.4","enterprise-8.0.0"]') }}
2536
services:
2637
couchbase:
2738
image: couchbase:${{ matrix.couchbase-server-version }}
@@ -69,17 +80,25 @@ jobs:
6980
- name: Initialize Couchbase cluster
7081
run: pnpm dlx tsx tests/scripts/initTestCluster.ts
7182

72-
- name: Vitest cache
73-
uses: actions/cache@v4
83+
- name: Restore vitest cache
84+
uses: actions/cache/restore@v4
7485
with:
75-
path: ./node_modules/.vite/vitest/results.json
76-
key: vitest-cache-${{ github.ref_name }}
86+
path: ./node_modules/.vite/results.json
87+
key: vitest-cache-${{ matrix.couchbase-server-version }}-${{ github.ref_name }}-${{ github.run_id }}-${{ github.run_attempt }}
7788
restore-keys: |
78-
vitest-cache-main
89+
vitest-cache-${{ matrix.couchbase-server-version }}-${{ github.ref_name }}-
90+
vitest-cache-${{ matrix.couchbase-server-version }}-main-
7991
8092
- name: Run all tests
8193
run: pnpm vitest --run --bail 5
8294

95+
- name: Save vitest cache
96+
if: always()
97+
uses: actions/cache/save@v4
98+
with:
99+
path: ./node_modules/.vite/results.json
100+
key: vitest-cache-${{ matrix.couchbase-server-version }}-${{ github.ref_name }}-${{ github.run_id }}-${{ github.run_attempt }}
101+
83102
- name: Upload Tests Report
84103
if: always()
85104
uses: actions/upload-artifact@v4

packages/cbjs/src/bucketmanager.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,8 @@ export class BucketSettings implements IBucketSettings {
374374

375375
/**
376376
* Specifies the number of vBuckets in this bucket
377+
*
378+
* @since Couchbase Server 7.6
377379
*/
378380
numVBuckets?: number;
379381

packages/cbjs/src/streamablepromises.ts

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
*/
1717
import { EventEmitter } from 'events';
1818

19-
import { EventKey, EventListener, EventMap, TypedEmitter } from './utils/TypedEmitter.js';
19+
import { EventKey, EventMap, TypedEmitter } from './utils/TypedEmitter.js';
2020

2121
/**
2222
* @internal
@@ -44,21 +44,19 @@ export class StreamablePromise<T, EM extends EventMap>
4444
})<EM>
4545
implements Promise<T>
4646
{
47-
private _promise: Promise<T> | null = null;
48-
private _promiseOns: [string | symbol, EventListener<any[]>][];
47+
private _promise: Promise<T>;
48+
protected _collectResults = true;
4949

5050
/**
5151
* @internal
5252
*/
5353
constructor(promisefyFn: PromisifyFunc<T, EM>) {
5454
super();
5555

56-
this._promiseOns = [];
5756
this._promise = new Promise((resolve, reject) => {
5857
promisefyFn(
5958
{
6059
on: <T extends EventKey<EM>>(eventName: T, listener: EM[T]) => {
61-
this._promiseOns.push([eventName, listener]);
6260
void super.on(eventName, listener);
6361
},
6462
},
@@ -68,42 +66,30 @@ export class StreamablePromise<T, EM extends EventMap>
6866
});
6967
}
7068

71-
private get promise(): Promise<T> {
72-
if (!this._promise) {
73-
throw new Error('Cannot await a promise that is already registered for events');
74-
}
75-
return this._promise;
76-
}
77-
78-
private _depromisify() {
79-
this._promiseOns.forEach((e) => void this.off(...(e as [never, never])));
80-
this._promise = null;
81-
}
82-
8369
then<TResult1 = T, TResult2 = never>(
8470
onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null,
8571
onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null
8672
): Promise<TResult1 | TResult2> {
87-
return this.promise.then<TResult1, TResult2>(onfulfilled, onrejected);
73+
return this._promise.then<TResult1, TResult2>(onfulfilled, onrejected);
8874
}
8975

9076
catch<TResult = never>(
9177
onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null
9278
): Promise<T | TResult> {
93-
return this.promise.catch<TResult>(onrejected);
79+
return this._promise.catch<TResult>(onrejected);
9480
}
9581

9682
finally(onfinally?: (() => void) | undefined | null): Promise<T> {
97-
return this.promise.finally(onfinally);
83+
return this._promise.finally(onfinally);
9884
}
9985

10086
override addListener<T extends EventKey<EM>>(eventName: T, listener: EM[T]): this {
101-
this._depromisify();
87+
this._collectResults = false;
10288
return super.on(eventName, listener);
10389
}
10490

10591
override on<T extends EventKey<EM>>(eventName: T, listener: EM[T]): this {
106-
this._depromisify();
92+
this._collectResults = false;
10793
return super.on(eventName, listener);
10894
}
10995

@@ -135,7 +121,9 @@ export class StreamableRowPromise<T, TRow, TMeta> extends StreamablePromise<
135121
const rows: TRow[] = [];
136122
let meta: TMeta | undefined;
137123

138-
void emitter.on('row', (r) => rows.push(r));
124+
void emitter.on('row', (r) => {
125+
if (this._collectResults) rows.push(r);
126+
});
139127
void emitter.on('meta', (m) => (meta = m));
140128
void emitter.on('error', (e) => (err = e));
141129
void emitter.on('end', () => {
@@ -167,7 +155,9 @@ export class StreamableReplicasPromise<T, TRep> extends StreamablePromise<
167155
let err: Error | undefined;
168156
const replicas: TRep[] = [];
169157

170-
void emitter.on('replica', (r) => replicas.push(r));
158+
void emitter.on('replica', (r) => {
159+
if (this._collectResults) replicas.push(r);
160+
});
171161
void emitter.on('error', (e) => (err = e));
172162
void emitter.on('end', () => {
173163
if (err) {
@@ -195,7 +185,9 @@ export class StreamableScanPromise<T, TRes> extends StreamablePromise<
195185
let err: Error | undefined;
196186
const results: TRes[] = [];
197187

198-
void emitter.on('result', (r) => results.push(r));
188+
void emitter.on('result', (r) => {
189+
if (this._collectResults) results.push(r);
190+
});
199191
void emitter.on('error', (e) => (err = e));
200192
void emitter.on('end', () => {
201193
if (err) {

packages/deploy/src/clusterChanges/applyCouchbaseClusterChanges.ts

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { retry } from 'ts-retry-promise';
22

3-
import { AnyCluster, Cluster, keyspacePath } from '@cbjsdev/cbjs';
3+
import { AnyCluster, keyspacePath } from '@cbjsdev/cbjs';
44
import {
55
CouchbaseHttpApiConfig,
66
createQueryIndex,
@@ -651,15 +651,15 @@ async function applyUpsertSearchIndex(
651651
.searchIndexes()
652652
.getAllIndexes();
653653

654-
const searchIndex = searchIndexes.find((s) => s.name === change.name);
654+
const searchIndex = searchIndexes.find((s) => s.name === config.name);
655655

656656
if (searchIndex) {
657657
config.uuid = searchIndex.uuid;
658658
config.sourceUUID = searchIndex.sourceUuid;
659659
}
660660

661661
console.log(
662-
`${getTimePrefix()} Requesting creation of search index "${change.bucket} # ${change.name}"`
662+
`${getTimePrefix()} Requesting upsert of search index "${change.bucket} # ${config.name}"`
663663
);
664664

665665
await cluster
@@ -669,19 +669,19 @@ async function applyUpsertSearchIndex(
669669
.upsertIndex(config, opts);
670670

671671
console.log(
672-
`${getTimePrefix()} Waiting for search index "${change.bucket} # ${change.name}" to be created`
672+
`${getTimePrefix()} Waiting for search index "${change.bucket} # ${config.name}" to be ready`
673673
);
674674
await waitForSearchIndex(
675675
apiConfig,
676-
change.name,
676+
config.name,
677677
{
678678
bucket: change.bucket,
679679
scope: change.scope,
680680
},
681681
opts
682682
);
683683
console.log(
684-
`${getTimePrefix()} Search index "${change.bucket} # ${change.name}" created`
684+
`${getTimePrefix()} Search index "${change.bucket} # ${config.name}" ready`
685685
);
686686
}
687687

@@ -692,30 +692,31 @@ async function applyDropSearchIndex(
692692
opts: ChangeOptions
693693
) {
694694
console.log(
695-
`${getTimePrefix()} Requesting deletion of search index "${change.bucket} # ${change.name}"`
695+
`${getTimePrefix()} Requesting deletion of search index "${change.bucket} # ${change.indexName}"`
696696
);
697697

698698
await cluster
699699
.bucket(change.bucket)
700700
.scope(change.scope)
701701
.searchIndexes()
702-
.dropIndex(change.name);
702+
.dropIndex(change.indexName);
703703

704704
console.log(
705-
`${getTimePrefix()} Waiting for search index "${change.bucket} # ${change.name}" to be deleted`
705+
`${getTimePrefix()} Waiting for search index "${change.bucket} # ${change.indexName}" to be deleted`
706706
);
707707
await waitForSearchIndex(
708708
apiConfig,
709-
change.name,
709+
change.indexName,
710710
{
711711
bucket: change.bucket,
712+
scope: change.scope,
712713
},
713714
{
714715
...opts,
715716
expectMissing: true,
716717
}
717718
);
718719
console.log(
719-
`${getTimePrefix()} Search index "${change.bucket} # ${change.name}" deleted`
720+
`${getTimePrefix()} Search index "${change.bucket} # ${change.indexName}" deleted`
720721
);
721722
}

packages/deploy/src/clusterChanges/getCouchbaseClusterChanges.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,7 @@ describe('getCouchbaseClusterChanges', () => {
681681
{
682682
type: 'dropSearchIndex',
683683
name: 'searchIndex1',
684+
indexName: 'searchIndex1',
684685
bucket: 'bucket1',
685686
scope: 'scope1',
686687
},

packages/deploy/src/clusterChanges/getCouchbaseClusterChanges.ts

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -685,12 +685,26 @@ function getObsoleteSearchIndexes(
685685

686686
return currentIndexes
687687
.filter((b) => !requestedIndexes.includes(b))
688-
.map((b) => ({
689-
type: 'dropSearchIndex',
690-
name: b,
691-
bucket: bucketName,
692-
scope: scopeName,
693-
}));
688+
.map((b) => {
689+
const currentIndexFn =
690+
currentConfig[bucketName]?.scopes[scopeName]?.searchIndexes?.[b];
691+
692+
invariant(currentIndexFn, 'Search index definition not found.');
693+
694+
const config = currentIndexFn({
695+
sourceName: bucketName,
696+
bucketName,
697+
scopeName,
698+
});
699+
700+
return {
701+
type: 'dropSearchIndex' as const,
702+
name: b,
703+
indexName: config.name,
704+
bucket: bucketName,
705+
scope: scopeName,
706+
};
707+
});
694708
}
695709

696710
function getNewSearchIndexes(

packages/deploy/src/clusterChanges/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,10 @@ export type CouchbaseClusterChangeDropSearchIndex = {
187187
* The config alias for the search index.
188188
*/
189189
name: string;
190+
/**
191+
* The actual index name on the cluster.
192+
*/
193+
indexName: string;
190194
};
191195

192196
export type CouchbaseClusterConfig = {

packages/http-client/src/services/kv/getCollections.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export async function getCollections(
2929
}
3030

3131
const body = (await response.json()) as ApiBucketScopes;
32-
const scope = body.scopes.find((s) => s.name);
32+
const scope = body.scopes.find((s) => s.name === scopeName);
3333

3434
if (scope === undefined) {
3535
throw new Error(`Scope '${bucketName}'.'${scopeName}' not found`);

0 commit comments

Comments
 (0)