@powersync/lib-services-framework 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/container.d.ts +8 -1
- package/dist/container.js +10 -1
- package/dist/container.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/locks/AbstractLockManager.d.ts +21 -0
- package/dist/locks/AbstractLockManager.js +34 -0
- package/dist/locks/AbstractLockManager.js.map +1 -0
- package/dist/locks/LockManager.d.ts +26 -0
- package/dist/locks/LockManager.js +7 -0
- package/dist/locks/LockManager.js.map +1 -0
- package/dist/locks/locks-index.d.ts +2 -0
- package/dist/locks/locks-index.js +3 -0
- package/dist/locks/locks-index.js.map +1 -0
- package/dist/migrations/AbstractMigrationAgent.d.ts +34 -0
- package/dist/migrations/AbstractMigrationAgent.js +139 -0
- package/dist/migrations/AbstractMigrationAgent.js.map +1 -0
- package/dist/migrations/MigrationManager.d.ts +11 -0
- package/dist/migrations/MigrationManager.js +28 -0
- package/dist/migrations/MigrationManager.js.map +1 -0
- package/dist/migrations/migration-definitions.d.ts +28 -0
- package/dist/migrations/migration-definitions.js +6 -0
- package/dist/migrations/migration-definitions.js.map +1 -0
- package/dist/migrations/migrations-index.d.ts +3 -0
- package/dist/migrations/migrations-index.js +4 -0
- package/dist/migrations/migrations-index.js.map +1 -0
- package/dist/utils/DisposableObserver.d.ts +5 -1
- package/dist/utils/DisposableObserver.js.map +1 -1
- package/package.json +3 -3
package/dist/container.d.ts
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import { ErrorReporter } from './alerts/definitions.js';
|
|
2
|
+
import { MigrationManager } from './migrations/MigrationManager.js';
|
|
2
3
|
import { ProbeModule, TerminationHandler } from './signals/signals-index.js';
|
|
3
4
|
export declare enum ContainerImplementation {
|
|
4
5
|
REPORTER = "reporter",
|
|
5
6
|
PROBES = "probes",
|
|
6
|
-
TERMINATION_HANDLER = "termination-handler"
|
|
7
|
+
TERMINATION_HANDLER = "termination-handler",
|
|
8
|
+
MIGRATION_MANAGER = "migration-manager"
|
|
7
9
|
}
|
|
8
10
|
export type ContainerImplementationTypes = {
|
|
9
11
|
[ContainerImplementation.REPORTER]: ErrorReporter;
|
|
10
12
|
[ContainerImplementation.PROBES]: ProbeModule;
|
|
11
13
|
[ContainerImplementation.TERMINATION_HANDLER]: TerminationHandler;
|
|
14
|
+
[ContainerImplementation.MIGRATION_MANAGER]: MigrationManager;
|
|
12
15
|
};
|
|
13
16
|
export type RegisterDefaultsOptions = {
|
|
14
17
|
skip?: ContainerImplementation[];
|
|
@@ -52,6 +55,10 @@ export declare class Container {
|
|
|
52
55
|
handleTerminationSignalLast: (handler: import("./signals/termination-handler.js").Handler) => void;
|
|
53
56
|
gracefully: <T>(exec: () => T | Promise<T>, handler: (component: T, signal: import("./signals/termination-handler.js").Signal) => Promise<void> | void) => Promise<T>;
|
|
54
57
|
};
|
|
58
|
+
/**
|
|
59
|
+
* Manager for system migrations.
|
|
60
|
+
*/
|
|
61
|
+
get migrationManager(): MigrationManager<import("./index.js").MigrationAgentGenerics>;
|
|
55
62
|
constructor();
|
|
56
63
|
/**
|
|
57
64
|
* Gets an implementation given an identifier.
|
package/dist/container.js
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
2
|
import { NoOpReporter } from './alerts/no-op-reporter.js';
|
|
3
|
+
import { MigrationManager } from './migrations/MigrationManager.js';
|
|
3
4
|
import { createFSProbe, createTerminationHandler } from './signals/signals-index.js';
|
|
4
5
|
export var ContainerImplementation;
|
|
5
6
|
(function (ContainerImplementation) {
|
|
6
7
|
ContainerImplementation["REPORTER"] = "reporter";
|
|
7
8
|
ContainerImplementation["PROBES"] = "probes";
|
|
8
9
|
ContainerImplementation["TERMINATION_HANDLER"] = "termination-handler";
|
|
10
|
+
ContainerImplementation["MIGRATION_MANAGER"] = "migration-manager";
|
|
9
11
|
})(ContainerImplementation || (ContainerImplementation = {}));
|
|
10
12
|
const DEFAULT_GENERATORS = {
|
|
11
13
|
[ContainerImplementation.REPORTER]: () => NoOpReporter,
|
|
12
14
|
[ContainerImplementation.PROBES]: () => createFSProbe(),
|
|
13
|
-
[ContainerImplementation.TERMINATION_HANDLER]: () => createTerminationHandler()
|
|
15
|
+
[ContainerImplementation.TERMINATION_HANDLER]: () => createTerminationHandler(),
|
|
16
|
+
[ContainerImplementation.MIGRATION_MANAGER]: () => new MigrationManager()
|
|
14
17
|
};
|
|
15
18
|
/**
|
|
16
19
|
* A container which provides means for registering and getting various
|
|
@@ -35,6 +38,12 @@ export class Container {
|
|
|
35
38
|
get terminationHandler() {
|
|
36
39
|
return this.getImplementation(ContainerImplementation.TERMINATION_HANDLER);
|
|
37
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Manager for system migrations.
|
|
43
|
+
*/
|
|
44
|
+
get migrationManager() {
|
|
45
|
+
return this.getImplementation(ContainerImplementation.MIGRATION_MANAGER);
|
|
46
|
+
}
|
|
38
47
|
constructor() {
|
|
39
48
|
this.implementations = new Map();
|
|
40
49
|
}
|
package/dist/container.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"container.js","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,QAAQ,CAAC;AAEvB,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAmC,aAAa,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAEtH,MAAM,CAAN,IAAY,
|
|
1
|
+
{"version":3,"file":"container.js","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,QAAQ,CAAC;AAEvB,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAmC,aAAa,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAEtH,MAAM,CAAN,IAAY,uBAKX;AALD,WAAY,uBAAuB;IACjC,gDAAqB,CAAA;IACrB,4CAAiB,CAAA;IACjB,sEAA2C,CAAA;IAC3C,kEAAuC,CAAA;AACzC,CAAC,EALW,uBAAuB,KAAvB,uBAAuB,QAKlC;AAiCD,MAAM,kBAAkB,GAA6C;IACnE,CAAC,uBAAuB,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAC,YAAY;IACtD,CAAC,uBAAuB,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,aAAa,EAAE;IACvD,CAAC,uBAAuB,CAAC,mBAAmB,CAAC,EAAE,GAAG,EAAE,CAAC,wBAAwB,EAAE;IAC/E,CAAC,uBAAuB,CAAC,iBAAiB,CAAC,EAAE,GAAG,EAAE,CAAC,IAAI,gBAAgB,EAAE;CAC1E,CAAC;AAEF;;;GAGG;AACH,MAAM,OAAO,SAAS;IAGpB;;OAEG;IACH,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,iBAAiB,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAChE,CAAC;IAED;;OAEG;IACH,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,iBAAiB,CAAC,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IAClE,CAAC;IAED;;OAEG;IACH,IAAI,kBAAkB;QACpB,OAAO,IAAI,CAAC,iBAAiB,CAAC,uBAAuB,CAAC,mBAAmB,CAAC,CAAC;IAC7E,CAAC;IAED;;OAEG;IACH,IAAI,gBAAgB;QAClB,OAAO,IAAI,CAAC,iBAAiB,CAAC,uBAAuB,CAAC,iBAAiB,CAAC,CAAC;IAC3E,CAAC;IAED;QACE,IAAI,CAAC,eAAe,GAAG,IAAI,GAAG,EAAE,CAAC;IACnC,CAAC;IAWD,iBAAiB,CAAI,UAAgC;QACnD,MAAM,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC5D,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,sBAAsB,MAAM,CAAC,UAAU,CAAC,2BAA2B,CAAC,CAAC;QACvF,CAAC;QACD,OAAO,cAAc,CAAC;IACxB,CAAC;IAWD,WAAW,CAAI,UAAgC;QAC7C,MAAM,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC5D,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,cAAc,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,gBAAgB,CAAC,OAAiC;QAChD,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,uBAAuB,CAAC,EAAE,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YACzF,MAAM,SAAS,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;YAC3C,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,QAAQ,CAAI,UAAgC,EAAE,cAAiB;QAC7D,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;IACvD,CAAC;CACF;AAED,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,SAAS,EAAE,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,10 @@ export * from './container.js';
|
|
|
6
6
|
export * from './errors/errors-index.js';
|
|
7
7
|
export * as errors from './errors/errors-index.js';
|
|
8
8
|
export * from './logger/Logger.js';
|
|
9
|
+
export * from './locks/locks-index.js';
|
|
10
|
+
export * as locks from './locks/locks-index.js';
|
|
11
|
+
export * from './migrations/migrations-index.js';
|
|
12
|
+
export * as migrations from './migrations/migrations-index.js';
|
|
9
13
|
export * from './schema/schema-index.js';
|
|
10
14
|
export * as schema from './schema/schema-index.js';
|
|
11
15
|
export * from './signals/signals-index.js';
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,10 @@ export * from './container.js';
|
|
|
6
6
|
export * from './errors/errors-index.js';
|
|
7
7
|
export * as errors from './errors/errors-index.js';
|
|
8
8
|
export * from './logger/Logger.js';
|
|
9
|
+
export * from './locks/locks-index.js';
|
|
10
|
+
export * as locks from './locks/locks-index.js';
|
|
11
|
+
export * from './migrations/migrations-index.js';
|
|
12
|
+
export * as migrations from './migrations/migrations-index.js';
|
|
9
13
|
export * from './schema/schema-index.js';
|
|
10
14
|
export * as schema from './schema/schema-index.js';
|
|
11
15
|
export * from './signals/signals-index.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,OAAO,KAAK,MAAM,MAAM,0BAA0B,CAAC;AAEnD,cAAc,wBAAwB,CAAC;AACvC,OAAO,KAAK,MAAM,MAAM,wBAAwB,CAAC;AAEjD,cAAc,gBAAgB,CAAC;AAE/B,cAAc,0BAA0B,CAAC;AACzC,OAAO,KAAK,MAAM,MAAM,0BAA0B,CAAC;AAEnD,cAAc,oBAAoB,CAAC;AAEnC,cAAc,0BAA0B,CAAC;AACzC,OAAO,KAAK,MAAM,MAAM,0BAA0B,CAAC;AAEnD,cAAc,4BAA4B,CAAC;AAC3C,OAAO,KAAK,OAAO,MAAM,4BAA4B,CAAC;AAEtD,cAAc,0BAA0B,CAAC;AACzC,OAAO,KAAK,MAAM,MAAM,0BAA0B,CAAC;AAEnD,cAAc,8BAA8B,CAAC;AAC7C,OAAO,KAAK,MAAM,MAAM,0BAA0B,CAAC;AAEnD,cAAc,wBAAwB,CAAC;AACvC,OAAO,KAAK,KAAK,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,OAAO,KAAK,MAAM,MAAM,0BAA0B,CAAC;AAEnD,cAAc,wBAAwB,CAAC;AACvC,OAAO,KAAK,MAAM,MAAM,wBAAwB,CAAC;AAEjD,cAAc,gBAAgB,CAAC;AAE/B,cAAc,0BAA0B,CAAC;AACzC,OAAO,KAAK,MAAM,MAAM,0BAA0B,CAAC;AAEnD,cAAc,oBAAoB,CAAC;AAEnC,cAAc,wBAAwB,CAAC;AACvC,OAAO,KAAK,KAAK,MAAM,wBAAwB,CAAC;AAEhD,cAAc,kCAAkC,CAAC;AACjD,OAAO,KAAK,UAAU,MAAM,kCAAkC,CAAC;AAE/D,cAAc,0BAA0B,CAAC;AACzC,OAAO,KAAK,MAAM,MAAM,0BAA0B,CAAC;AAEnD,cAAc,4BAA4B,CAAC;AAC3C,OAAO,KAAK,OAAO,MAAM,4BAA4B,CAAC;AAEtD,cAAc,0BAA0B,CAAC;AACzC,OAAO,KAAK,MAAM,MAAM,0BAA0B,CAAC;AAEnD,cAAc,8BAA8B,CAAC;AAC7C,OAAO,KAAK,MAAM,MAAM,0BAA0B,CAAC;AAEnD,cAAc,wBAAwB,CAAC;AACvC,OAAO,KAAK,KAAK,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { LockAcquireOptions, LockCallback, LockHandle, LockManager } from './LockManager.js';
|
|
2
|
+
export type LockManagerParams = {
|
|
3
|
+
/**
|
|
4
|
+
* Name of the process/user trying to acquire the lock.
|
|
5
|
+
*/
|
|
6
|
+
name: string;
|
|
7
|
+
/**
|
|
8
|
+
* The TTL of the lock (ms). Default: 60000 ms (1 min)
|
|
9
|
+
*/
|
|
10
|
+
timeout?: number;
|
|
11
|
+
};
|
|
12
|
+
export declare abstract class AbstractLockManager implements LockManager {
|
|
13
|
+
protected params: LockManagerParams;
|
|
14
|
+
constructor(params: LockManagerParams);
|
|
15
|
+
/**
|
|
16
|
+
* Implementation specific method for acquiring a lock handle.
|
|
17
|
+
*/
|
|
18
|
+
protected abstract acquireHandle(): Promise<LockHandle | null>;
|
|
19
|
+
acquire(options?: LockAcquireOptions): Promise<LockHandle | null>;
|
|
20
|
+
lock(handler: LockCallback, options?: LockAcquireOptions): Promise<void>;
|
|
21
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { LockActiveError } from './LockManager.js';
|
|
2
|
+
export class AbstractLockManager {
|
|
3
|
+
constructor(params) {
|
|
4
|
+
this.params = params;
|
|
5
|
+
}
|
|
6
|
+
async acquire(options) {
|
|
7
|
+
const { max_wait_ms = 0 } = options ?? {};
|
|
8
|
+
let handle = null;
|
|
9
|
+
const start = new Date();
|
|
10
|
+
do {
|
|
11
|
+
handle = await this.acquireHandle();
|
|
12
|
+
if (handle) {
|
|
13
|
+
return handle;
|
|
14
|
+
}
|
|
15
|
+
else if (max_wait_ms) {
|
|
16
|
+
await new Promise((r) => setTimeout(r, max_wait_ms / 10));
|
|
17
|
+
}
|
|
18
|
+
} while (new Date().getTime() - start.getTime() < max_wait_ms);
|
|
19
|
+
return handle;
|
|
20
|
+
}
|
|
21
|
+
async lock(handler, options) {
|
|
22
|
+
const handle = await this.acquire(options);
|
|
23
|
+
if (!handle) {
|
|
24
|
+
throw new LockActiveError();
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
await handler(() => handle.refresh());
|
|
28
|
+
}
|
|
29
|
+
finally {
|
|
30
|
+
await handle.release();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=AbstractLockManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AbstractLockManager.js","sourceRoot":"","sources":["../../src/locks/AbstractLockManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,eAAe,EAAyC,MAAM,kBAAkB,CAAC;AAa9G,MAAM,OAAgB,mBAAmB;IACvC,YAAsB,MAAyB;QAAzB,WAAM,GAAN,MAAM,CAAmB;IAAG,CAAC;IAOnD,KAAK,CAAC,OAAO,CAAC,OAA4B;QACxC,MAAM,EAAE,WAAW,GAAG,CAAC,EAAE,GAAG,OAAO,IAAI,EAAE,CAAC;QAC1C,IAAI,MAAM,GAAsB,IAAI,CAAC;QACrC,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC;QACzB,GAAG,CAAC;YACF,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;YACpC,IAAI,MAAM,EAAE,CAAC;gBACX,OAAO,MAAM,CAAC;YAChB,CAAC;iBAAM,IAAI,WAAW,EAAE,CAAC;gBACvB,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,WAAW,GAAG,EAAE,CAAC,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,GAAG,WAAW,EAAE;QAE/D,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAAqB,EAAE,OAA4B;QAC5D,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC3C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,eAAe,EAAE,CAAC;QAC9B,CAAC;QACD,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;QACxC,CAAC;gBAAS,CAAC;YACT,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;QACzB,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export declare class LockActiveError extends Error {
|
|
2
|
+
constructor();
|
|
3
|
+
}
|
|
4
|
+
export type LockAcquireOptions = {
|
|
5
|
+
/**
|
|
6
|
+
* Optionally retry and wait for the lock to be acquired
|
|
7
|
+
*/
|
|
8
|
+
max_wait_ms?: number;
|
|
9
|
+
};
|
|
10
|
+
export type LockHandle = {
|
|
11
|
+
refresh(): Promise<void>;
|
|
12
|
+
release(): Promise<void>;
|
|
13
|
+
};
|
|
14
|
+
export type LockCallback = (refresh: () => Promise<void>) => Promise<void>;
|
|
15
|
+
export type LockManager = {
|
|
16
|
+
init?(): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Attempts to acquire a lock handle.
|
|
19
|
+
* @returns null if the lock is in use and either no `max_wait_ms` was provided or the timeout has elapsed.
|
|
20
|
+
*/
|
|
21
|
+
acquire(options?: LockAcquireOptions): Promise<LockHandle | null>;
|
|
22
|
+
/**
|
|
23
|
+
* Acquires a lock, executes the given handler callback then automatically releases the lock.
|
|
24
|
+
*/
|
|
25
|
+
lock(handler: LockCallback, options?: LockAcquireOptions): Promise<void>;
|
|
26
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LockManager.js","sourceRoot":"","sources":["../../src/locks/LockManager.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACxC;QACE,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;IACpC,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locks-index.js","sourceRoot":"","sources":["../../src/locks/locks-index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { LockManager } from '../locks/LockManager.js';
|
|
2
|
+
import * as defs from './migration-definitions.js';
|
|
3
|
+
export type MigrationParams<Generics extends MigrationAgentGenerics = MigrationAgentGenerics> = {
|
|
4
|
+
count?: number;
|
|
5
|
+
direction: defs.Direction;
|
|
6
|
+
migrationContext?: Generics['MIGRATION_CONTEXT'];
|
|
7
|
+
};
|
|
8
|
+
type WriteLogsParams = {
|
|
9
|
+
state?: defs.MigrationState;
|
|
10
|
+
log_stream: Iterable<defs.ExecutedMigration> | AsyncIterable<defs.ExecutedMigration>;
|
|
11
|
+
};
|
|
12
|
+
export type MigrationAgentGenerics = {
|
|
13
|
+
MIGRATION_CONTEXT?: {};
|
|
14
|
+
};
|
|
15
|
+
export type RunMigrationParams<Generics extends MigrationAgentGenerics = MigrationAgentGenerics> = MigrationParams & {
|
|
16
|
+
migrations: defs.Migration<Generics['MIGRATION_CONTEXT']>[];
|
|
17
|
+
maxLockWaitMs?: number;
|
|
18
|
+
};
|
|
19
|
+
type ExecuteParams = RunMigrationParams & {
|
|
20
|
+
state?: defs.MigrationState;
|
|
21
|
+
};
|
|
22
|
+
export declare const DEFAULT_MAX_LOCK_WAIT_MS: number;
|
|
23
|
+
export declare abstract class AbstractMigrationAgent<Generics extends MigrationAgentGenerics = MigrationAgentGenerics> implements AsyncDisposable {
|
|
24
|
+
abstract get store(): defs.MigrationStore;
|
|
25
|
+
abstract get locks(): LockManager;
|
|
26
|
+
abstract loadInternalMigrations(): Promise<defs.Migration<Generics['MIGRATION_CONTEXT']>[]>;
|
|
27
|
+
abstract [Symbol.asyncDispose](): Promise<void>;
|
|
28
|
+
protected init(): Promise<void>;
|
|
29
|
+
run(params: RunMigrationParams): Promise<void>;
|
|
30
|
+
protected execute(params: ExecuteParams): AsyncGenerator<defs.ExecutedMigration>;
|
|
31
|
+
resetStore(): Promise<void>;
|
|
32
|
+
protected writeLogsToStore: (params: WriteLogsParams) => Promise<void>;
|
|
33
|
+
}
|
|
34
|
+
export {};
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { logger } from '../logger/Logger.js';
|
|
2
|
+
import * as defs from './migration-definitions.js';
|
|
3
|
+
export const DEFAULT_MAX_LOCK_WAIT_MS = 3 * 60 * 1000; // 3 minutes
|
|
4
|
+
export class AbstractMigrationAgent {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.writeLogsToStore = async (params) => {
|
|
7
|
+
const log = [...(params.state?.log || [])];
|
|
8
|
+
for await (const migration of params.log_stream) {
|
|
9
|
+
log.push(migration);
|
|
10
|
+
await this.store.save({
|
|
11
|
+
last_run: migration.name,
|
|
12
|
+
log: log
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
async init() {
|
|
18
|
+
await this.locks.init?.();
|
|
19
|
+
await this.store.init?.();
|
|
20
|
+
}
|
|
21
|
+
async run(params) {
|
|
22
|
+
await this.init();
|
|
23
|
+
const { direction, migrations, migrationContext } = params;
|
|
24
|
+
// Only one process should execute this at a time.
|
|
25
|
+
logger.info('Acquiring lock for migrations');
|
|
26
|
+
const lockHandle = await this.locks.acquire({ max_wait_ms: params.maxLockWaitMs ?? DEFAULT_MAX_LOCK_WAIT_MS });
|
|
27
|
+
if (!lockHandle) {
|
|
28
|
+
throw new Error('Could not acquire lock');
|
|
29
|
+
}
|
|
30
|
+
let isReleased = false;
|
|
31
|
+
const releaseLock = async () => {
|
|
32
|
+
if (isReleased) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
await lockHandle.release();
|
|
36
|
+
isReleased = true;
|
|
37
|
+
};
|
|
38
|
+
// For the case where the migration is terminated
|
|
39
|
+
process.addListener('beforeExit', releaseLock);
|
|
40
|
+
try {
|
|
41
|
+
const state = await this.store.load();
|
|
42
|
+
logger.info('Running migrations');
|
|
43
|
+
const logStream = this.execute({
|
|
44
|
+
direction,
|
|
45
|
+
migrations,
|
|
46
|
+
state,
|
|
47
|
+
migrationContext
|
|
48
|
+
});
|
|
49
|
+
await this.writeLogsToStore({
|
|
50
|
+
log_stream: logStream,
|
|
51
|
+
state
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
finally {
|
|
55
|
+
logger.info('Releasing migration lock');
|
|
56
|
+
await releaseLock();
|
|
57
|
+
process.removeListener('beforeExit', releaseLock);
|
|
58
|
+
logger.info('Done with migrations');
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async *execute(params) {
|
|
62
|
+
const internalMigrations = await this.loadInternalMigrations();
|
|
63
|
+
let migrations = [...internalMigrations, ...params.migrations];
|
|
64
|
+
if (params.direction === defs.Direction.Down) {
|
|
65
|
+
migrations.reverse();
|
|
66
|
+
}
|
|
67
|
+
let index = 0;
|
|
68
|
+
if (params.state) {
|
|
69
|
+
// Find the index of the last run
|
|
70
|
+
const { last_run, log } = params.state;
|
|
71
|
+
index = migrations.findIndex((migration) => {
|
|
72
|
+
return migration.name === params.state.last_run;
|
|
73
|
+
});
|
|
74
|
+
if (index === -1) {
|
|
75
|
+
throw new Error(`The last run migration ${params.state?.last_run} was not found in the given set of migrations`);
|
|
76
|
+
}
|
|
77
|
+
// Get the last log entry for the last run migration
|
|
78
|
+
// This should technically be the last (sorted ascending) log entry.
|
|
79
|
+
// Sorting in descending order
|
|
80
|
+
const lastLogEntry = log
|
|
81
|
+
.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime())
|
|
82
|
+
.find((log) => log.name == last_run);
|
|
83
|
+
// There should be a log entry for this
|
|
84
|
+
if (!lastLogEntry) {
|
|
85
|
+
throw new Error(`Could not find last migration log entry for ${last_run}`);
|
|
86
|
+
}
|
|
87
|
+
// If we are migrating up:
|
|
88
|
+
// If the last run was an up migration:
|
|
89
|
+
// Then we want to start at the next migration index
|
|
90
|
+
// If after a previous Down migration
|
|
91
|
+
// Then we need to start at the current migration index
|
|
92
|
+
// If we are migrating down:
|
|
93
|
+
// If the previous migration was a down migration
|
|
94
|
+
// Then we need to start at the next index
|
|
95
|
+
// If the previous migration was an up migration
|
|
96
|
+
// Then we want to include the last run (up) migration
|
|
97
|
+
if ((params.direction === defs.Direction.Up && lastLogEntry.direction == defs.Direction.Up) ||
|
|
98
|
+
(params.direction == defs.Direction.Down && lastLogEntry.direction == defs.Direction.Down)) {
|
|
99
|
+
index += 1;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
migrations = migrations.slice(index);
|
|
103
|
+
let i = 0;
|
|
104
|
+
const { migrationContext } = params;
|
|
105
|
+
for (const migration of migrations) {
|
|
106
|
+
if (params.count && params.count === i) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
logger.info(`Executing ${migration.name} (${params.direction})`);
|
|
110
|
+
try {
|
|
111
|
+
switch (params.direction) {
|
|
112
|
+
case defs.Direction.Up: {
|
|
113
|
+
await migration.up(migrationContext);
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
case defs.Direction.Down: {
|
|
117
|
+
await migration.down(migrationContext);
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
logger.debug(`Success`);
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
logger.error(`Failed`, err);
|
|
125
|
+
process.exit(1);
|
|
126
|
+
}
|
|
127
|
+
yield {
|
|
128
|
+
name: migration.name,
|
|
129
|
+
direction: params.direction,
|
|
130
|
+
timestamp: new Date()
|
|
131
|
+
};
|
|
132
|
+
i++;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
resetStore() {
|
|
136
|
+
return this.store.clear();
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=AbstractMigrationAgent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AbstractMigrationAgent.js","sourceRoot":"","sources":["../../src/migrations/AbstractMigrationAgent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { AbstractMigrationAgent, MigrationAgentGenerics, MigrationParams } from './AbstractMigrationAgent.js';
|
|
2
|
+
import * as defs from './migration-definitions.js';
|
|
3
|
+
export declare class MigrationManager<Generics extends MigrationAgentGenerics = MigrationAgentGenerics> implements AsyncDisposable {
|
|
4
|
+
private migrations;
|
|
5
|
+
private _agent;
|
|
6
|
+
constructor();
|
|
7
|
+
registerMigrationAgent(agent: AbstractMigrationAgent<Generics>): void;
|
|
8
|
+
registerMigrations(migrations: defs.Migration<Generics['MIGRATION_CONTEXT']>[]): void;
|
|
9
|
+
migrate(params: MigrationParams<Generics>): Promise<void>;
|
|
10
|
+
[Symbol.asyncDispose](): Promise<void | undefined>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export class MigrationManager {
|
|
2
|
+
constructor() {
|
|
3
|
+
this.migrations = [];
|
|
4
|
+
this._agent = null;
|
|
5
|
+
}
|
|
6
|
+
registerMigrationAgent(agent) {
|
|
7
|
+
if (this._agent) {
|
|
8
|
+
throw new Error(`A migration agent has already been registered. Only a single agent is supported.`);
|
|
9
|
+
}
|
|
10
|
+
this._agent = agent;
|
|
11
|
+
}
|
|
12
|
+
registerMigrations(migrations) {
|
|
13
|
+
this.migrations.push(...migrations);
|
|
14
|
+
}
|
|
15
|
+
async migrate(params) {
|
|
16
|
+
if (!this._agent) {
|
|
17
|
+
throw new Error(`A migration agent has not been registered yet.`);
|
|
18
|
+
}
|
|
19
|
+
return this._agent.run({
|
|
20
|
+
...params,
|
|
21
|
+
migrations: this.migrations
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
async [Symbol.asyncDispose]() {
|
|
25
|
+
return this._agent?.[Symbol.asyncDispose]();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=MigrationManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MigrationManager.js","sourceRoot":"","sources":["../../src/migrations/MigrationManager.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,gBAAgB;IAM3B;QACE,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACrB,CAAC;IAED,sBAAsB,CAAC,KAAuC;QAC5D,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,kFAAkF,CAAC,CAAC;QACtG,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,CAAC;IAED,kBAAkB,CAAC,UAA2D;QAC5E,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,MAAiC;QAC7C,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;QACpE,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;YACrB,GAAG,MAAM;YACT,UAAU,EAAE,IAAI,CAAC,UAAU;SAC5B,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC;QACzB,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC;IAC9C,CAAC;CACF"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export type MigrationFunction<Context extends {} | undefined = undefined> = (context: Context) => Promise<void>;
|
|
2
|
+
export type Migration<Context extends {} | undefined = undefined> = {
|
|
3
|
+
name: string;
|
|
4
|
+
up: MigrationFunction<Context>;
|
|
5
|
+
down: MigrationFunction<Context>;
|
|
6
|
+
};
|
|
7
|
+
export declare enum Direction {
|
|
8
|
+
Up = "up",
|
|
9
|
+
Down = "down"
|
|
10
|
+
}
|
|
11
|
+
export type ExecutedMigration = {
|
|
12
|
+
name: string;
|
|
13
|
+
direction: Direction;
|
|
14
|
+
timestamp: Date;
|
|
15
|
+
};
|
|
16
|
+
export type MigrationState = {
|
|
17
|
+
last_run: string;
|
|
18
|
+
log: ExecutedMigration[];
|
|
19
|
+
};
|
|
20
|
+
export type MigrationStore = {
|
|
21
|
+
init?: () => Promise<void>;
|
|
22
|
+
load: () => Promise<MigrationState | undefined>;
|
|
23
|
+
save: (state: MigrationState) => Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Resets the migration store state. Mostly used for tests.
|
|
26
|
+
*/
|
|
27
|
+
clear: () => Promise<void>;
|
|
28
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-definitions.js","sourceRoot":"","sources":["../../src/migrations/migration-definitions.ts"],"names":[],"mappings":"AAQA,MAAM,CAAN,IAAY,SAGX;AAHD,WAAY,SAAS;IACnB,sBAAS,CAAA;IACT,0BAAa,CAAA;AACf,CAAC,EAHW,SAAS,KAAT,SAAS,QAGpB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrations-index.js","sourceRoot":"","sources":["../../src/migrations/migrations-index.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC"}
|
|
@@ -5,13 +5,17 @@ export interface DisposableListener {
|
|
|
5
5
|
*/
|
|
6
6
|
disposed: () => void;
|
|
7
7
|
}
|
|
8
|
-
export interface
|
|
8
|
+
export interface ManagedObserverClient<T extends DisposableListener> extends ObserverClient<T> {
|
|
9
9
|
/**
|
|
10
10
|
* Registers a listener that is automatically disposed when the parent is disposed.
|
|
11
11
|
* This is useful for disposing nested listeners.
|
|
12
12
|
*/
|
|
13
13
|
registerManagedListener: (parent: DisposableObserverClient<DisposableListener>, cb: Partial<T>) => () => void;
|
|
14
14
|
}
|
|
15
|
+
export interface DisposableObserverClient<T extends DisposableListener> extends ManagedObserverClient<T>, Disposable {
|
|
16
|
+
}
|
|
17
|
+
export interface AsyncDisposableObserverClient<T extends DisposableListener> extends ManagedObserverClient<T>, AsyncDisposable {
|
|
18
|
+
}
|
|
15
19
|
export declare class DisposableObserver<T extends DisposableListener> extends BaseObserver<T> implements DisposableObserverClient<T> {
|
|
16
20
|
registerManagedListener(parent: DisposableObserverClient<DisposableListener>, cb: Partial<T>): () => void;
|
|
17
21
|
[Symbol.dispose](): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DisposableObserver.js","sourceRoot":"","sources":["../../src/utils/DisposableObserver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAkB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"DisposableObserver.js","sourceRoot":"","sources":["../../src/utils/DisposableObserver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAkB,MAAM,mBAAmB,CAAC;AAsBjE,MAAM,OAAO,kBACX,SAAQ,YAAe;IAGvB,uBAAuB,CAAC,MAAoD,EAAE,EAAc;QAC1F,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;QAC3C,MAAM,CAAC,gBAAgB,CAAC;YACtB,QAAQ,EAAE,GAAG,EAAE;gBACb,QAAQ,EAAE,CAAC;YACb,CAAC;SACF,CAAC,CAAC;QACH,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,CAAC,MAAM,CAAC,OAAO,CAAC;QACd,IAAI,CAAC,gBAAgB,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAC/C,uBAAuB;QACvB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3E,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@powersync/lib-services-framework",
|
|
3
3
|
"repository": "https://github.com/powersync-ja/powersync-service",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.4.0",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -16,10 +16,10 @@
|
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"ajv": "^8.12.0",
|
|
18
18
|
"better-ajv-errors": "^1.2.0",
|
|
19
|
-
"bson": "^6.
|
|
19
|
+
"bson": "^6.8.0",
|
|
20
20
|
"dotenv": "^16.4.5",
|
|
21
21
|
"lodash": "^4.17.21",
|
|
22
|
-
"ts-codec": "^1.
|
|
22
|
+
"ts-codec": "^1.3.0",
|
|
23
23
|
"uuid": "^9.0.1",
|
|
24
24
|
"winston": "^3.13.0",
|
|
25
25
|
"zod": "^3.23.8"
|