@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.
Files changed (102) hide show
  1. package/LICENSE +67 -0
  2. package/README.md +3 -0
  3. package/dist/alerts/alerts-index.d.ts +2 -0
  4. package/dist/alerts/alerts-index.js +3 -0
  5. package/dist/alerts/alerts-index.js.map +1 -0
  6. package/dist/alerts/definitions.d.ts +13 -0
  7. package/dist/alerts/definitions.js +2 -0
  8. package/dist/alerts/definitions.js.map +1 -0
  9. package/dist/alerts/no-op-reporter.d.ts +2 -0
  10. package/dist/alerts/no-op-reporter.js +5 -0
  11. package/dist/alerts/no-op-reporter.js.map +1 -0
  12. package/dist/codec/codec-index.d.ts +2 -0
  13. package/dist/codec/codec-index.js +3 -0
  14. package/dist/codec/codec-index.js.map +1 -0
  15. package/dist/codec/codecs.d.ts +26 -0
  16. package/dist/codec/codecs.js +60 -0
  17. package/dist/codec/codecs.js.map +1 -0
  18. package/dist/codec/parsers.d.ts +15 -0
  19. package/dist/codec/parsers.js +56 -0
  20. package/dist/codec/parsers.js.map +1 -0
  21. package/dist/container.d.ts +48 -0
  22. package/dist/container.js +61 -0
  23. package/dist/container.js.map +1 -0
  24. package/dist/errors/errors-index.d.ts +2 -0
  25. package/dist/errors/errors-index.js +3 -0
  26. package/dist/errors/errors-index.js.map +1 -0
  27. package/dist/errors/framework-errors.d.ts +50 -0
  28. package/dist/errors/framework-errors.js +104 -0
  29. package/dist/errors/framework-errors.js.map +1 -0
  30. package/dist/errors/utils.d.ts +4 -0
  31. package/dist/errors/utils.js +18 -0
  32. package/dist/errors/utils.js.map +1 -0
  33. package/dist/index.d.ts +18 -0
  34. package/dist/index.js +19 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/logger/Logger.d.ts +6 -0
  37. package/dist/logger/Logger.js +13 -0
  38. package/dist/logger/Logger.js.map +1 -0
  39. package/dist/logger/logger-index.d.ts +1 -0
  40. package/dist/logger/logger-index.js +2 -0
  41. package/dist/logger/logger-index.js.map +1 -0
  42. package/dist/router/endpoint.d.ts +7 -0
  43. package/dist/router/endpoint.js +18 -0
  44. package/dist/router/endpoint.js.map +1 -0
  45. package/dist/router/router-definitions.d.ts +44 -0
  46. package/dist/router/router-definitions.js +14 -0
  47. package/dist/router/router-definitions.js.map +1 -0
  48. package/dist/router/router-index.d.ts +3 -0
  49. package/dist/router/router-index.js +4 -0
  50. package/dist/router/router-index.js.map +1 -0
  51. package/dist/router/router-response.d.ts +24 -0
  52. package/dist/router/router-response.js +32 -0
  53. package/dist/router/router-response.js.map +1 -0
  54. package/dist/schema/definitions.d.ts +16 -0
  55. package/dist/schema/definitions.js +2 -0
  56. package/dist/schema/definitions.js.map +1 -0
  57. package/dist/schema/json-schema/keywords.d.ts +2 -0
  58. package/dist/schema/json-schema/keywords.js +27 -0
  59. package/dist/schema/json-schema/keywords.js.map +1 -0
  60. package/dist/schema/json-schema/parser.d.ts +39 -0
  61. package/dist/schema/json-schema/parser.js +100 -0
  62. package/dist/schema/json-schema/parser.js.map +1 -0
  63. package/dist/schema/schema-index.d.ts +5 -0
  64. package/dist/schema/schema-index.js +6 -0
  65. package/dist/schema/schema-index.js.map +1 -0
  66. package/dist/schema/utils.d.ts +15 -0
  67. package/dist/schema/utils.js +40 -0
  68. package/dist/schema/utils.js.map +1 -0
  69. package/dist/schema/validators/schema-validator.d.ts +21 -0
  70. package/dist/schema/validators/schema-validator.js +55 -0
  71. package/dist/schema/validators/schema-validator.js.map +1 -0
  72. package/dist/schema/validators/ts-codec-validator.d.ts +11 -0
  73. package/dist/schema/validators/ts-codec-validator.js +14 -0
  74. package/dist/schema/validators/ts-codec-validator.js.map +1 -0
  75. package/dist/signals/probes/fs-probes.d.ts +2 -0
  76. package/dist/signals/probes/fs-probes.js +43 -0
  77. package/dist/signals/probes/fs-probes.js.map +1 -0
  78. package/dist/signals/probes/memory-probes.d.ts +5 -0
  79. package/dist/signals/probes/memory-probes.js +29 -0
  80. package/dist/signals/probes/memory-probes.js.map +1 -0
  81. package/dist/signals/probes/probes.d.ts +12 -0
  82. package/dist/signals/probes/probes.js +2 -0
  83. package/dist/signals/probes/probes.js.map +1 -0
  84. package/dist/signals/signals-index.d.ts +4 -0
  85. package/dist/signals/signals-index.js +5 -0
  86. package/dist/signals/signals-index.js.map +1 -0
  87. package/dist/signals/termination-handler.d.ts +42 -0
  88. package/dist/signals/termination-handler.js +89 -0
  89. package/dist/signals/termination-handler.js.map +1 -0
  90. package/dist/system/LifeCycledSystem.d.ts +23 -0
  91. package/dist/system/LifeCycledSystem.js +32 -0
  92. package/dist/system/LifeCycledSystem.js.map +1 -0
  93. package/dist/system/system-index.d.ts +1 -0
  94. package/dist/system/system-index.js +2 -0
  95. package/dist/system/system-index.js.map +1 -0
  96. package/dist/utils/environment-variables.d.ts +11 -0
  97. package/dist/utils/environment-variables.js +51 -0
  98. package/dist/utils/environment-variables.js.map +1 -0
  99. package/dist/utils/utils-index.d.ts +1 -0
  100. package/dist/utils/utils-index.js +2 -0
  101. package/dist/utils/utils-index.js.map +1 -0
  102. 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,2 @@
1
+ import { ProbeModule } from './probes.js';
2
+ export declare const createFSProbe: (dir?: string) => ProbeModule;
@@ -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,5 @@
1
+ import { ProbeModule } from './probes.js';
2
+ export type ProbeParams = {
3
+ poll_timeout_ms: number;
4
+ };
5
+ export declare const createInMemoryProbe: (params?: ProbeParams) => ProbeModule;
@@ -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,12 @@
1
+ export type ProbeState = {
2
+ ready: boolean;
3
+ started: boolean;
4
+ touched_at: Date;
5
+ };
6
+ export type ProbeModule = {
7
+ poll_timeout: number;
8
+ state(): ProbeState;
9
+ ready(): Promise<void>;
10
+ unready(): Promise<void>;
11
+ touch(): Promise<void>;
12
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=probes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"probes.js","sourceRoot":"","sources":["../../../src/signals/probes/probes.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ export * from './probes/fs-probes.js';
2
+ export * from './probes/memory-probes.js';
3
+ export * from './probes/probes.js';
4
+ export * from './termination-handler.js';
@@ -0,0 +1,5 @@
1
+ export * from './probes/fs-probes.js';
2
+ export * from './probes/memory-probes.js';
3
+ export * from './probes/probes.js';
4
+ export * from './termination-handler.js';
5
+ //# sourceMappingURL=signals-index.js.map
@@ -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,2 @@
1
+ export * from './LifeCycledSystem.js';
2
+ //# sourceMappingURL=system-index.js.map
@@ -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,2 @@
1
+ export * from './environment-variables.js';
2
+ //# sourceMappingURL=utils-index.js.map
@@ -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
+ }