@powersync/lib-services-framework 0.0.0-dev-20240620165410
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/LICENSE +67 -0
- package/README.md +3 -0
- package/dist/alerts/alerts-index.d.ts +2 -0
- package/dist/alerts/alerts-index.js +3 -0
- package/dist/alerts/alerts-index.js.map +1 -0
- package/dist/alerts/definitions.d.ts +13 -0
- package/dist/alerts/definitions.js +2 -0
- package/dist/alerts/definitions.js.map +1 -0
- package/dist/alerts/no-op-reporter.d.ts +2 -0
- package/dist/alerts/no-op-reporter.js +5 -0
- package/dist/alerts/no-op-reporter.js.map +1 -0
- package/dist/codec/codec-index.d.ts +2 -0
- package/dist/codec/codec-index.js +3 -0
- package/dist/codec/codec-index.js.map +1 -0
- package/dist/codec/codecs.d.ts +26 -0
- package/dist/codec/codecs.js +60 -0
- package/dist/codec/codecs.js.map +1 -0
- package/dist/codec/parsers.d.ts +15 -0
- package/dist/codec/parsers.js +56 -0
- package/dist/codec/parsers.js.map +1 -0
- package/dist/container.d.ts +48 -0
- package/dist/container.js +61 -0
- package/dist/container.js.map +1 -0
- package/dist/errors/errors-index.d.ts +2 -0
- package/dist/errors/errors-index.js +3 -0
- package/dist/errors/errors-index.js.map +1 -0
- package/dist/errors/framework-errors.d.ts +50 -0
- package/dist/errors/framework-errors.js +104 -0
- package/dist/errors/framework-errors.js.map +1 -0
- package/dist/errors/utils.d.ts +4 -0
- package/dist/errors/utils.js +18 -0
- package/dist/errors/utils.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/logger/Logger.d.ts +6 -0
- package/dist/logger/Logger.js +13 -0
- package/dist/logger/Logger.js.map +1 -0
- package/dist/logger/logger-index.d.ts +1 -0
- package/dist/logger/logger-index.js +2 -0
- package/dist/logger/logger-index.js.map +1 -0
- package/dist/router/endpoint.d.ts +7 -0
- package/dist/router/endpoint.js +18 -0
- package/dist/router/endpoint.js.map +1 -0
- package/dist/router/router-definitions.d.ts +44 -0
- package/dist/router/router-definitions.js +14 -0
- package/dist/router/router-definitions.js.map +1 -0
- package/dist/router/router-index.d.ts +3 -0
- package/dist/router/router-index.js +4 -0
- package/dist/router/router-index.js.map +1 -0
- package/dist/router/router-response.d.ts +24 -0
- package/dist/router/router-response.js +32 -0
- package/dist/router/router-response.js.map +1 -0
- package/dist/schema/definitions.d.ts +16 -0
- package/dist/schema/definitions.js +2 -0
- package/dist/schema/definitions.js.map +1 -0
- package/dist/schema/json-schema/keywords.d.ts +2 -0
- package/dist/schema/json-schema/keywords.js +27 -0
- package/dist/schema/json-schema/keywords.js.map +1 -0
- package/dist/schema/json-schema/parser.d.ts +39 -0
- package/dist/schema/json-schema/parser.js +100 -0
- package/dist/schema/json-schema/parser.js.map +1 -0
- package/dist/schema/schema-index.d.ts +5 -0
- package/dist/schema/schema-index.js +6 -0
- package/dist/schema/schema-index.js.map +1 -0
- package/dist/schema/utils.d.ts +15 -0
- package/dist/schema/utils.js +40 -0
- package/dist/schema/utils.js.map +1 -0
- package/dist/schema/validators/schema-validator.d.ts +21 -0
- package/dist/schema/validators/schema-validator.js +55 -0
- package/dist/schema/validators/schema-validator.js.map +1 -0
- package/dist/schema/validators/ts-codec-validator.d.ts +11 -0
- package/dist/schema/validators/ts-codec-validator.js +14 -0
- package/dist/schema/validators/ts-codec-validator.js.map +1 -0
- package/dist/signals/probes/fs-probes.d.ts +2 -0
- package/dist/signals/probes/fs-probes.js +43 -0
- package/dist/signals/probes/fs-probes.js.map +1 -0
- package/dist/signals/probes/memory-probes.d.ts +5 -0
- package/dist/signals/probes/memory-probes.js +29 -0
- package/dist/signals/probes/memory-probes.js.map +1 -0
- package/dist/signals/probes/probes.d.ts +12 -0
- package/dist/signals/probes/probes.js +2 -0
- package/dist/signals/probes/probes.js.map +1 -0
- package/dist/signals/signals-index.d.ts +4 -0
- package/dist/signals/signals-index.js +5 -0
- package/dist/signals/signals-index.js.map +1 -0
- package/dist/signals/termination-handler.d.ts +42 -0
- package/dist/signals/termination-handler.js +89 -0
- package/dist/signals/termination-handler.js.map +1 -0
- package/dist/system/LifeCycledSystem.d.ts +23 -0
- package/dist/system/LifeCycledSystem.js +32 -0
- package/dist/system/LifeCycledSystem.js.map +1 -0
- package/dist/system/system-index.d.ts +1 -0
- package/dist/system/system-index.js +2 -0
- package/dist/system/system-index.js.map +1 -0
- package/dist/utils/environment-variables.d.ts +11 -0
- package/dist/utils/environment-variables.js +51 -0
- package/dist/utils/environment-variables.js.map +1 -0
- package/dist/utils/utils-index.d.ts +1 -0
- package/dist/utils/utils-index.js +2 -0
- package/dist/utils/utils-index.js.map +1 -0
- package/package.json +36 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ts-codec-validator.js","sourceRoot":"","sources":["../../../src/schema/validators/ts-codec-validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,UAAU,CAAC;AAE9B,OAAO,KAAK,gBAAgB,MAAM,uBAAuB,CAAC;AAE1D,OAAO,KAAK,MAAM,MAAM,4BAA4B,CAAC;AAWrD;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CACpC,KAAQ,EACR,OAA6B,EACL,EAAE;IAC1B,MAAM,MAAM,GAAG,CAAC,CAAC,kBAAkB,CAAC,KAAK,EAAE;QACzC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC;QAClB,OAAO,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,IAAI,EAAE,CAAC,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC;KAC1D,CAAC,CAAC;IACH,OAAO,gBAAgB,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC;AACxD,CAAC,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as fs from 'node:fs/promises';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import { createInMemoryProbe } from './memory-probes.js';
|
|
4
|
+
export const createFSProbe = (dir = path.join(process.cwd(), '.probes')) => {
|
|
5
|
+
const memory_probe = createInMemoryProbe();
|
|
6
|
+
const startup_path = path.join(dir, 'startup');
|
|
7
|
+
const readiness_path = path.join(dir, 'ready');
|
|
8
|
+
/**
|
|
9
|
+
* Note this is different to Journey Micro.
|
|
10
|
+
* Updated here from `alive` to `poll` as per previous comment:
|
|
11
|
+
* FIXME: The above probe touches the wrong file
|
|
12
|
+
* */
|
|
13
|
+
const liveness_path = path.join(dir, 'poll');
|
|
14
|
+
const touchFile = async (path) => {
|
|
15
|
+
try {
|
|
16
|
+
await fs.mkdir(dir, {
|
|
17
|
+
recursive: true
|
|
18
|
+
});
|
|
19
|
+
await fs.writeFile(path, `${Date.now()}`);
|
|
20
|
+
}
|
|
21
|
+
catch (err) { }
|
|
22
|
+
};
|
|
23
|
+
return {
|
|
24
|
+
poll_timeout: memory_probe.poll_timeout,
|
|
25
|
+
state: memory_probe.state,
|
|
26
|
+
async ready() {
|
|
27
|
+
await Promise.all([touchFile(startup_path), touchFile(readiness_path)]);
|
|
28
|
+
await memory_probe.ready();
|
|
29
|
+
},
|
|
30
|
+
async unready() {
|
|
31
|
+
try {
|
|
32
|
+
await fs.unlink(readiness_path);
|
|
33
|
+
}
|
|
34
|
+
catch (err) { }
|
|
35
|
+
await memory_probe.unready();
|
|
36
|
+
},
|
|
37
|
+
async touch() {
|
|
38
|
+
await touchFile(liveness_path);
|
|
39
|
+
await memory_probe.touch();
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
//# sourceMappingURL=fs-probes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs-probes.js","sourceRoot":"","sources":["../../../src/signals/probes/fs-probes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAGzD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,MAAc,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,EAAe,EAAE;IAC9F,MAAM,YAAY,GAAG,mBAAmB,EAAE,CAAC;IAE3C,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC/C,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC/C;;;;UAIM;IACN,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAE7C,MAAM,SAAS,GAAG,KAAK,EAAE,IAAY,EAAE,EAAE;QACvC,IAAI;YACF,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE;gBAClB,SAAS,EAAE,IAAI;aAChB,CAAC,CAAC;YACH,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;SAC3C;QAAC,OAAO,GAAG,EAAE,GAAE;IAClB,CAAC,CAAC;IAEF,OAAO;QACL,YAAY,EAAE,YAAY,CAAC,YAAY;QACvC,KAAK,EAAE,YAAY,CAAC,KAAK;QAEzB,KAAK,CAAC,KAAK;YACT,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;YACxE,MAAM,YAAY,CAAC,KAAK,EAAE,CAAC;QAC7B,CAAC;QACD,KAAK,CAAC,OAAO;YACX,IAAI;gBACF,MAAM,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;aACjC;YAAC,OAAO,GAAG,EAAE,GAAE;YAChB,MAAM,YAAY,CAAC,OAAO,EAAE,CAAC;QAC/B,CAAC;QACD,KAAK,CAAC,KAAK;YACT,MAAM,SAAS,CAAC,aAAa,CAAC,CAAC;YAC/B,MAAM,YAAY,CAAC,KAAK,EAAE,CAAC;QAC7B,CAAC;KACF,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export const createInMemoryProbe = (params) => {
|
|
2
|
+
const state = {
|
|
3
|
+
ready: false,
|
|
4
|
+
started: false,
|
|
5
|
+
touched_at: new Date()
|
|
6
|
+
};
|
|
7
|
+
return {
|
|
8
|
+
poll_timeout: params?.poll_timeout_ms ?? 10000,
|
|
9
|
+
state: () => {
|
|
10
|
+
return {
|
|
11
|
+
ready: state.ready,
|
|
12
|
+
started: state.started,
|
|
13
|
+
touched_at: state.touched_at
|
|
14
|
+
};
|
|
15
|
+
},
|
|
16
|
+
ready: async () => {
|
|
17
|
+
state.ready = true;
|
|
18
|
+
state.started = true;
|
|
19
|
+
state.touched_at = new Date();
|
|
20
|
+
},
|
|
21
|
+
unready: async () => {
|
|
22
|
+
state.ready = false;
|
|
23
|
+
},
|
|
24
|
+
touch: async () => {
|
|
25
|
+
state.touched_at = new Date();
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=memory-probes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-probes.js","sourceRoot":"","sources":["../../../src/signals/probes/memory-probes.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,MAAoB,EAAe,EAAE;IACvE,MAAM,KAAK,GAAe;QACxB,KAAK,EAAE,KAAK;QACZ,OAAO,EAAE,KAAK;QACd,UAAU,EAAE,IAAI,IAAI,EAAE;KACvB,CAAC;IAEF,OAAO;QACL,YAAY,EAAE,MAAM,EAAE,eAAe,IAAI,KAAK;QAE9C,KAAK,EAAE,GAAG,EAAE;YACV,OAAO;gBACL,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,UAAU,EAAE,KAAK,CAAC,UAAU;aAC7B,CAAC;QACJ,CAAC;QACD,KAAK,EAAE,KAAK,IAAI,EAAE;YAChB,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;YACnB,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;YACrB,KAAK,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC;QAChC,CAAC;QACD,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;QACtB,CAAC;QACD,KAAK,EAAE,KAAK,IAAI,EAAE;YAChB,KAAK,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC;QAChC,CAAC;KACF,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probes.js","sourceRoot":"","sources":["../../../src/signals/probes/probes.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signals-index.js","sourceRoot":"","sources":["../../src/signals/signals-index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export declare enum Signal {
|
|
2
|
+
SIGTERM = "SIGTERM",
|
|
3
|
+
SIGINT = "SIGINT",
|
|
4
|
+
SIGUSR2 = "SIGUSR2"
|
|
5
|
+
}
|
|
6
|
+
export type Handler = (event: Signal) => void | Promise<void>;
|
|
7
|
+
type TerminationHandlerParams = {
|
|
8
|
+
/**
|
|
9
|
+
* A list of process signals to listen for.
|
|
10
|
+
*
|
|
11
|
+
* @default ['SIGTERM', 'SIGINT', 'SIGUSR2']
|
|
12
|
+
*/
|
|
13
|
+
signals?: Signal[];
|
|
14
|
+
/**
|
|
15
|
+
* The timeout for all handlers to complete. Once this is reached the process will be exited
|
|
16
|
+
*/
|
|
17
|
+
timeout_ms?: number;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Utility function to handle external termination signals.
|
|
21
|
+
* Calls an async handler and then kills the application.
|
|
22
|
+
*/
|
|
23
|
+
export declare const createTerminationHandler: (params?: TerminationHandlerParams) => {
|
|
24
|
+
/**
|
|
25
|
+
* Register a termination handler to be run when a termination signal is received. Calling
|
|
26
|
+
* this function will register the termination handler at the start of the list resulting
|
|
27
|
+
* in handlers being called in the reverse order to how they were registered.
|
|
28
|
+
*
|
|
29
|
+
* Use `handleTerminationSignalLast` if you want to register the handler at the end.
|
|
30
|
+
*/
|
|
31
|
+
handleTerminationSignal: (handler: Handler) => void;
|
|
32
|
+
/**
|
|
33
|
+
* This is the same as `handleTerminationSignal` except it will register a termination handler
|
|
34
|
+
* at the end of the list - resulting in it being run after existing termination handlers.
|
|
35
|
+
*
|
|
36
|
+
* Use `handleTerminationSignal` if you want to register the handler at the start.
|
|
37
|
+
*/
|
|
38
|
+
handleTerminationSignalLast: (handler: Handler) => void;
|
|
39
|
+
gracefully: <T>(exec: () => T | Promise<T>, handler: (component: T, signal: Signal) => Promise<void> | void) => Promise<T>;
|
|
40
|
+
};
|
|
41
|
+
export type TerminationHandler = ReturnType<typeof createTerminationHandler>;
|
|
42
|
+
export {};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import _ from 'lodash';
|
|
2
|
+
import { logger } from '../logger/Logger.js';
|
|
3
|
+
export var Signal;
|
|
4
|
+
(function (Signal) {
|
|
5
|
+
Signal["SIGTERM"] = "SIGTERM";
|
|
6
|
+
Signal["SIGINT"] = "SIGINT";
|
|
7
|
+
Signal["SIGUSR2"] = "SIGUSR2";
|
|
8
|
+
})(Signal || (Signal = {}));
|
|
9
|
+
/**
|
|
10
|
+
* Utility function to handle external termination signals.
|
|
11
|
+
* Calls an async handler and then kills the application.
|
|
12
|
+
*/
|
|
13
|
+
export const createTerminationHandler = (params) => {
|
|
14
|
+
const { signals = Object.values(Signal), timeout_ms = 30000 } = params || {};
|
|
15
|
+
const handlers = [];
|
|
16
|
+
let signal_received = false;
|
|
17
|
+
const signalHandler = (signal) => {
|
|
18
|
+
if (signal === Signal.SIGINT) {
|
|
19
|
+
logger.info('Send ^C again to force exit');
|
|
20
|
+
}
|
|
21
|
+
if (signal_received) {
|
|
22
|
+
// The SIGINT signal is sent on ctrl-c - if the user presses ctrl-c twice then we
|
|
23
|
+
// hard exit
|
|
24
|
+
if (signal === Signal.SIGINT) {
|
|
25
|
+
logger.info('Received second ^C. Exiting');
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
signal_received = true;
|
|
31
|
+
new Promise(async (resolve) => {
|
|
32
|
+
logger.info('Terminating gracefully ...');
|
|
33
|
+
for (const handler of handlers) {
|
|
34
|
+
try {
|
|
35
|
+
await handler(signal);
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
logger.error('Failed to execute termination handler', err);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
logger.info('Exiting');
|
|
42
|
+
resolve();
|
|
43
|
+
}).then(() => {
|
|
44
|
+
process.exit(0);
|
|
45
|
+
});
|
|
46
|
+
setTimeout(() => {
|
|
47
|
+
logger.error('Timed out waiting for program to exit. Force exiting');
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}, timeout_ms);
|
|
50
|
+
};
|
|
51
|
+
// This debounce is needed as certain executors (like npm, pnpm) seem to send kill signals multiple times. This debounce
|
|
52
|
+
// prevents the termination handler from immediately exiting under those circumstances
|
|
53
|
+
const debouncedSignalHandler = _.debounce(signalHandler, 1000, {
|
|
54
|
+
leading: true,
|
|
55
|
+
trailing: false
|
|
56
|
+
});
|
|
57
|
+
for (const signal of signals) {
|
|
58
|
+
process.on(signal, () => debouncedSignalHandler(signal));
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
/**
|
|
62
|
+
* Register a termination handler to be run when a termination signal is received. Calling
|
|
63
|
+
* this function will register the termination handler at the start of the list resulting
|
|
64
|
+
* in handlers being called in the reverse order to how they were registered.
|
|
65
|
+
*
|
|
66
|
+
* Use `handleTerminationSignalLast` if you want to register the handler at the end.
|
|
67
|
+
*/
|
|
68
|
+
handleTerminationSignal: (handler) => {
|
|
69
|
+
handlers.unshift(handler);
|
|
70
|
+
},
|
|
71
|
+
/**
|
|
72
|
+
* This is the same as `handleTerminationSignal` except it will register a termination handler
|
|
73
|
+
* at the end of the list - resulting in it being run after existing termination handlers.
|
|
74
|
+
*
|
|
75
|
+
* Use `handleTerminationSignal` if you want to register the handler at the start.
|
|
76
|
+
*/
|
|
77
|
+
handleTerminationSignalLast: (handler) => {
|
|
78
|
+
handlers.push(handler);
|
|
79
|
+
},
|
|
80
|
+
gracefully: async (exec, handler) => {
|
|
81
|
+
const component = await exec();
|
|
82
|
+
handlers.unshift((signal) => {
|
|
83
|
+
return handler(component, signal);
|
|
84
|
+
});
|
|
85
|
+
return component;
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
//# sourceMappingURL=termination-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"termination-handler.js","sourceRoot":"","sources":["../../src/signals/termination-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An interface that can be used to create a stateful System. A System is an entity
|
|
3
|
+
* which contains state, generally in the form of connections, that must be stated
|
|
4
|
+
* and stopped gracefully along with a services lifecycle.
|
|
5
|
+
*
|
|
6
|
+
* A System can contain anything but should offer a `start` and `stop` operation
|
|
7
|
+
*/
|
|
8
|
+
export type LifecycleCallback<T> = (singleton: T) => Promise<void> | void;
|
|
9
|
+
export type PartialLifecycle<T> = {
|
|
10
|
+
start?: LifecycleCallback<T>;
|
|
11
|
+
stop?: LifecycleCallback<T>;
|
|
12
|
+
};
|
|
13
|
+
export type ComponentLifecycle<T> = PartialLifecycle<T> & {
|
|
14
|
+
component: T;
|
|
15
|
+
};
|
|
16
|
+
export type LifecycleHandler<T> = () => ComponentLifecycle<T>;
|
|
17
|
+
export declare abstract class LifeCycledSystem {
|
|
18
|
+
components: ComponentLifecycle<any>[];
|
|
19
|
+
constructor();
|
|
20
|
+
withLifecycle: <T>(component: T, lifecycle: PartialLifecycle<T>) => T;
|
|
21
|
+
start: () => Promise<void>;
|
|
22
|
+
stop: () => Promise<void>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An interface that can be used to create a stateful System. A System is an entity
|
|
3
|
+
* which contains state, generally in the form of connections, that must be stated
|
|
4
|
+
* and stopped gracefully along with a services lifecycle.
|
|
5
|
+
*
|
|
6
|
+
* A System can contain anything but should offer a `start` and `stop` operation
|
|
7
|
+
*/
|
|
8
|
+
import { container } from '../container.js';
|
|
9
|
+
export class LifeCycledSystem {
|
|
10
|
+
constructor() {
|
|
11
|
+
this.components = [];
|
|
12
|
+
this.withLifecycle = (component, lifecycle) => {
|
|
13
|
+
this.components.push({
|
|
14
|
+
component: component,
|
|
15
|
+
...lifecycle
|
|
16
|
+
});
|
|
17
|
+
return component;
|
|
18
|
+
};
|
|
19
|
+
this.start = async () => {
|
|
20
|
+
for (const lifecycle of this.components) {
|
|
21
|
+
await lifecycle.start?.(lifecycle.component);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
this.stop = async () => {
|
|
25
|
+
for (const lifecycle of this.components.reverse()) {
|
|
26
|
+
await lifecycle.stop?.(lifecycle.component);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
container.terminationHandler.handleTerminationSignal(() => this.stop());
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=LifeCycledSystem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LifeCycledSystem.js","sourceRoot":"","sources":["../../src/system/LifeCycledSystem.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAc5C,MAAM,OAAgB,gBAAgB;IAGpC;QAFA,eAAU,GAA8B,EAAE,CAAC;QAM3C,kBAAa,GAAG,CAAI,SAAY,EAAE,SAA8B,EAAK,EAAE;YACrE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;gBACnB,SAAS,EAAE,SAAS;gBACpB,GAAG,SAAS;aACb,CAAC,CAAC;YACH,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC;QAEF,UAAK,GAAG,KAAK,IAAI,EAAE;YACjB,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE;gBACvC,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;aAC9C;QACH,CAAC,CAAC;QAEF,SAAI,GAAG,KAAK,IAAI,EAAE;YAChB,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE;gBACjD,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;aAC7C;QACH,CAAC,CAAC;QArBA,SAAS,CAAC,kBAAkB,CAAC,uBAAuB,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1E,CAAC;CAqBF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './LifeCycledSystem.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system-index.js","sourceRoot":"","sources":["../../src/system/system-index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as t from 'zod';
|
|
2
|
+
export declare const DefaultSchema: t.ZodObject<{}, "strip", t.ZodTypeAny, {}, {}>;
|
|
3
|
+
export type DefaultSchema = t.infer<typeof DefaultSchema>;
|
|
4
|
+
export declare const collectEnvironmentVariablesFromSchema: <T extends t.ZodType<any, t.ZodTypeDef, any>>(schema: T, override?: Record<string, any>) => t.TypeOf<T>;
|
|
5
|
+
export declare const collectEnvironmentVariables: <T extends t.ZodRawShape>(schema: T, override?: Record<string, any>) => { [k in keyof t.objectUtil.addQuestionMarks<t.baseObjectOutputType<T>, any>]: t.objectUtil.addQuestionMarks<t.baseObjectOutputType<T>, any>[k]; } & {};
|
|
6
|
+
export declare const type: {
|
|
7
|
+
string: t.ZodString;
|
|
8
|
+
number: t.ZodEffects<t.ZodEffects<t.ZodString, string, string>, number, string>;
|
|
9
|
+
boolean: t.ZodEffects<t.ZodEffects<t.ZodString, string, string>, boolean | undefined, string>;
|
|
10
|
+
list: t.ZodEffects<t.ZodString, string[], string>;
|
|
11
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import * as dotenv from 'dotenv';
|
|
2
|
+
import * as t from 'zod';
|
|
3
|
+
const string = t.string();
|
|
4
|
+
const number = t
|
|
5
|
+
.string()
|
|
6
|
+
.refine((value) => !isNaN(parseInt(value)))
|
|
7
|
+
.transform((value) => parseInt(value));
|
|
8
|
+
const convertToBoolean = (value) => {
|
|
9
|
+
switch (value) {
|
|
10
|
+
case '1':
|
|
11
|
+
case 'true': {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
case '0':
|
|
15
|
+
case 'false': {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
const boolean = t
|
|
21
|
+
.string()
|
|
22
|
+
.refine((value) => ['0', '1', 'true', 'false'].includes(value))
|
|
23
|
+
.transform(convertToBoolean);
|
|
24
|
+
const list = t.string().transform((value) => value.split(','));
|
|
25
|
+
export const DefaultSchema = t.object({});
|
|
26
|
+
export const collectEnvironmentVariablesFromSchema = (schema, override) => {
|
|
27
|
+
let env;
|
|
28
|
+
if (override) {
|
|
29
|
+
env = override;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
dotenv.config();
|
|
33
|
+
env = process.env;
|
|
34
|
+
}
|
|
35
|
+
const result = schema.safeParse(env);
|
|
36
|
+
if (!result.success) {
|
|
37
|
+
console.log(JSON.stringify(result.error.format(), null, 2));
|
|
38
|
+
throw new Error('Invalid or missing environment variables');
|
|
39
|
+
}
|
|
40
|
+
return result.data;
|
|
41
|
+
};
|
|
42
|
+
export const collectEnvironmentVariables = (schema, override) => {
|
|
43
|
+
return collectEnvironmentVariablesFromSchema(t.object(schema).and(DefaultSchema), override);
|
|
44
|
+
};
|
|
45
|
+
export const type = {
|
|
46
|
+
string,
|
|
47
|
+
number,
|
|
48
|
+
boolean,
|
|
49
|
+
list
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=environment-variables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"environment-variables.js","sourceRoot":"","sources":["../../src/utils/environment-variables.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;AAC1B,MAAM,MAAM,GAAG,CAAC;KACb,MAAM,EAAE;KACR,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;KAC1C,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;AAEzC,MAAM,gBAAgB,GAAG,CAAC,KAAa,EAAE,EAAE;IACzC,QAAQ,KAAK,EAAE;QACb,KAAK,GAAG,CAAC;QACT,KAAK,MAAM,CAAC,CAAC;YACX,OAAO,IAAI,CAAC;SACb;QACD,KAAK,GAAG,CAAC;QACT,KAAK,OAAO,CAAC,CAAC;YACZ,OAAO,KAAK,CAAC;SACd;KACF;AACH,CAAC,CAAC;AACF,MAAM,OAAO,GAAG,CAAC;KACd,MAAM,EAAE;KACR,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;KAC9D,SAAS,CAAC,gBAAgB,CAAC,CAAC;AAE/B,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AAE/D,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAG1C,MAAM,CAAC,MAAM,qCAAqC,GAAG,CACnD,MAAS,EACT,QAA8B,EAClB,EAAE;IACd,IAAI,GAAG,CAAC;IACR,IAAI,QAAQ,EAAE;QACZ,GAAG,GAAG,QAAQ,CAAC;KAChB;SAAM;QACL,MAAM,CAAC,MAAM,EAAE,CAAC;QAChB,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;KACnB;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAErC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;QACnB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC5D,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;KAC7D;IAED,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAA0B,MAAS,EAAE,QAA8B,EAAE,EAAE;IAChH,OAAO,qCAAqC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,QAAQ,CAAC,CAAC;AAC9F,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,IAAI,GAAG;IAClB,MAAM;IACN,MAAM;IACN,OAAO;IACP,IAAI;CACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './environment-variables.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils-index.js","sourceRoot":"","sources":["../../src/utils/utils-index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@powersync/lib-services-framework",
|
|
3
|
+
"repository": "https://github.com/powersync-ja/powersync-service",
|
|
4
|
+
"version": "0.0.0-dev-20240620165410",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"license": "FSL-1.1-Apache-2.0",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist/**/*"
|
|
11
|
+
],
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [],
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"ajv": "^8.12.0",
|
|
18
|
+
"better-ajv-errors": "^1.2.0",
|
|
19
|
+
"bson": "^6.6.0",
|
|
20
|
+
"dotenv": "^16.4.5",
|
|
21
|
+
"lodash": "^4.17.21",
|
|
22
|
+
"ts-codec": "^1.2.2",
|
|
23
|
+
"winston": "^3.13.0",
|
|
24
|
+
"zod": "^3.23.8"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/lodash": "^4.17.5",
|
|
28
|
+
"vitest": "^0.34.6"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"clean": "rm -r ./dist && tsc -b --clean",
|
|
32
|
+
"build": "tsc -b",
|
|
33
|
+
"build:tests": "tsc -b test/tsconfig.json",
|
|
34
|
+
"test": "vitest"
|
|
35
|
+
}
|
|
36
|
+
}
|