@powersync/service-core 1.10.1 → 1.10.3

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 (68) hide show
  1. package/.probes/poll +1 -0
  2. package/CHANGELOG.md +12 -0
  3. package/dist/sync/sync.js +8 -1
  4. package/dist/sync/sync.js.map +1 -1
  5. package/package.json +3 -3
  6. package/src/sync/sync.ts +8 -1
  7. package/test/dist/auth.test.d.ts +1 -0
  8. package/test/dist/auth.test.js +332 -0
  9. package/test/dist/auth.test.js.map +1 -0
  10. package/test/dist/broadcast_iterable.test.d.ts +1 -0
  11. package/test/dist/broadcast_iterable.test.js +131 -0
  12. package/test/dist/broadcast_iterable.test.js.map +1 -0
  13. package/test/dist/bucket_validation.d.ts +26 -0
  14. package/test/dist/bucket_validation.js +56 -0
  15. package/test/dist/bucket_validation.js.map +1 -0
  16. package/test/dist/bucket_validation.test.d.ts +1 -0
  17. package/test/dist/bucket_validation.test.js +134 -0
  18. package/test/dist/bucket_validation.test.js.map +1 -0
  19. package/test/dist/checksum_cache.test.d.ts +1 -0
  20. package/test/dist/checksum_cache.test.js +375 -0
  21. package/test/dist/checksum_cache.test.js.map +1 -0
  22. package/test/dist/compacting.test.d.ts +1 -0
  23. package/test/dist/compacting.test.js +254 -0
  24. package/test/dist/compacting.test.js.map +1 -0
  25. package/test/dist/data_storage.test.d.ts +1 -0
  26. package/test/dist/data_storage.test.js +1306 -0
  27. package/test/dist/data_storage.test.js.map +1 -0
  28. package/test/dist/demultiplexer.test.d.ts +1 -0
  29. package/test/dist/demultiplexer.test.js +166 -0
  30. package/test/dist/demultiplexer.test.js.map +1 -0
  31. package/test/dist/env.d.ts +3 -0
  32. package/test/dist/env.js +5 -0
  33. package/test/dist/env.js.map +1 -0
  34. package/test/dist/merge_iterable.test.d.ts +1 -0
  35. package/test/dist/merge_iterable.test.js +321 -0
  36. package/test/dist/merge_iterable.test.js.map +1 -0
  37. package/test/dist/routes/probes.integration.test.d.ts +1 -0
  38. package/test/dist/routes/probes.integration.test.js +192 -0
  39. package/test/dist/routes/probes.integration.test.js.map +1 -0
  40. package/test/dist/routes/probes.test.d.ts +1 -0
  41. package/test/dist/routes/probes.test.js +119 -0
  42. package/test/dist/routes/probes.test.js.map +1 -0
  43. package/test/dist/setup.d.ts +1 -0
  44. package/test/dist/setup.js +7 -0
  45. package/test/dist/setup.js.map +1 -0
  46. package/test/dist/stream_utils.d.ts +6 -0
  47. package/test/dist/stream_utils.js +37 -0
  48. package/test/dist/stream_utils.js.map +1 -0
  49. package/test/dist/sync/BucketChecksumState.test.d.ts +1 -0
  50. package/test/dist/sync/BucketChecksumState.test.js +499 -0
  51. package/test/dist/sync/BucketChecksumState.test.js.map +1 -0
  52. package/test/dist/sync/checksum_state.test.d.ts +1 -0
  53. package/test/dist/sync/checksum_state.test.js +21 -0
  54. package/test/dist/sync/checksum_state.test.js.map +1 -0
  55. package/test/dist/sync/util.test.d.ts +1 -0
  56. package/test/dist/sync/util.test.js +28 -0
  57. package/test/dist/sync/util.test.js.map +1 -0
  58. package/test/dist/sync.test.d.ts +1 -0
  59. package/test/dist/sync.test.js +428 -0
  60. package/test/dist/sync.test.js.map +1 -0
  61. package/test/dist/util.d.ts +36 -0
  62. package/test/dist/util.js +114 -0
  63. package/test/dist/util.js.map +1 -0
  64. package/test/dist/util.test.d.ts +1 -0
  65. package/test/dist/util.test.js +45 -0
  66. package/test/dist/util.test.js.map +1 -0
  67. package/test/tsconfig.tsbuildinfo +1 -0
  68. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1,192 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import Fastify from 'fastify';
3
+ import { container } from '@powersync/lib-services-framework';
4
+ import * as auth from '../../../src/routes/auth.js';
5
+ import { configureFastifyServer } from '../../../src/index.js';
6
+ import { ProbeRoutes } from '../../../src/routes/endpoints/probes.js';
7
+ vi.mock('@powersync/lib-services-framework', async () => {
8
+ const actual = (await vi.importActual('@powersync/lib-services-framework'));
9
+ return {
10
+ ...actual,
11
+ container: {
12
+ ...actual.container,
13
+ probes: {
14
+ state: vi.fn()
15
+ }
16
+ }
17
+ };
18
+ });
19
+ describe('Probe Routes Integration', () => {
20
+ let app;
21
+ let mockSystem;
22
+ beforeEach(async () => {
23
+ app = Fastify();
24
+ mockSystem = { routerEngine: {} };
25
+ await configureFastifyServer(app, { service_context: mockSystem });
26
+ await app.ready();
27
+ });
28
+ afterEach(async () => {
29
+ await app.close();
30
+ });
31
+ describe('Startup Probe', () => {
32
+ it('returns 200 when system is started', async () => {
33
+ const mockState = {
34
+ started: true,
35
+ ready: true,
36
+ touched_at: new Date()
37
+ };
38
+ vi.spyOn(auth, 'authUser').mockResolvedValue({ authorized: true });
39
+ vi.mocked(container.probes.state).mockReturnValue(mockState);
40
+ const response = await app.inject({
41
+ method: 'GET',
42
+ url: ProbeRoutes.STARTUP
43
+ });
44
+ expect(response.statusCode).toBe(200);
45
+ expect(JSON.parse(response.payload)).toEqual({
46
+ ...mockState,
47
+ touched_at: mockState.touched_at.toISOString()
48
+ });
49
+ });
50
+ it('returns 400 when system is not started', async () => {
51
+ const mockState = {
52
+ started: false,
53
+ ready: false,
54
+ touched_at: new Date()
55
+ };
56
+ vi.mocked(container.probes.state).mockReturnValue(mockState);
57
+ const response = await app.inject({
58
+ method: 'GET',
59
+ url: ProbeRoutes.STARTUP
60
+ });
61
+ expect(response.statusCode).toBe(400);
62
+ expect(JSON.parse(response.payload)).toEqual({
63
+ ...mockState,
64
+ touched_at: mockState.touched_at.toISOString()
65
+ });
66
+ });
67
+ });
68
+ describe('Liveness Probe', () => {
69
+ it('returns 200 when system was touched recently', async () => {
70
+ const mockState = {
71
+ started: true,
72
+ ready: true,
73
+ touched_at: new Date()
74
+ };
75
+ vi.mocked(container.probes.state).mockReturnValue(mockState);
76
+ const response = await app.inject({
77
+ method: 'GET',
78
+ url: ProbeRoutes.LIVENESS
79
+ });
80
+ expect(response.statusCode).toBe(200);
81
+ expect(JSON.parse(response.payload)).toEqual({
82
+ ...mockState,
83
+ touched_at: mockState.touched_at.toISOString()
84
+ });
85
+ });
86
+ it('returns 400 when system has not been touched recently', async () => {
87
+ const mockState = {
88
+ started: true,
89
+ ready: true,
90
+ touched_at: new Date(Date.now() - 15000) // 15 seconds ago
91
+ };
92
+ vi.mocked(container.probes.state).mockReturnValue(mockState);
93
+ const response = await app.inject({
94
+ method: 'GET',
95
+ url: ProbeRoutes.LIVENESS
96
+ });
97
+ expect(response.statusCode).toBe(400);
98
+ expect(JSON.parse(response.payload)).toEqual({
99
+ ...mockState,
100
+ touched_at: mockState.touched_at.toISOString()
101
+ });
102
+ });
103
+ });
104
+ describe('Readiness Probe', () => {
105
+ it('returns 200 when system is ready', async () => {
106
+ const mockState = {
107
+ started: true,
108
+ ready: true,
109
+ touched_at: new Date()
110
+ };
111
+ vi.mocked(container.probes.state).mockReturnValue(mockState);
112
+ const response = await app.inject({
113
+ method: 'GET',
114
+ url: ProbeRoutes.READINESS
115
+ });
116
+ expect(response.statusCode).toBe(200);
117
+ expect(JSON.parse(response.payload)).toEqual({
118
+ ...mockState,
119
+ touched_at: mockState.touched_at.toISOString()
120
+ });
121
+ });
122
+ it('returns 400 when system is not ready', async () => {
123
+ const mockState = {
124
+ started: true,
125
+ ready: false,
126
+ touched_at: new Date()
127
+ };
128
+ vi.mocked(container.probes.state).mockReturnValue(mockState);
129
+ const response = await app.inject({
130
+ method: 'GET',
131
+ url: ProbeRoutes.READINESS
132
+ });
133
+ expect(response.statusCode).toBe(400);
134
+ expect(JSON.parse(response.payload)).toEqual({
135
+ ...mockState,
136
+ touched_at: mockState.touched_at.toISOString()
137
+ });
138
+ });
139
+ });
140
+ describe('Request Queue Behavior', () => {
141
+ it('handles concurrent requests within limits', async () => {
142
+ const mockState = { started: true, ready: true, touched_at: new Date() };
143
+ vi.mocked(container.probes.state).mockReturnValue(mockState);
144
+ // Create array of 15 concurrent requests (default concurrency is 10)
145
+ const requests = Array(15)
146
+ .fill(null)
147
+ .map(() => app.inject({
148
+ method: 'GET',
149
+ url: ProbeRoutes.STARTUP
150
+ }));
151
+ const responses = await Promise.all(requests);
152
+ // All requests should complete successfully
153
+ responses.forEach((response) => {
154
+ expect(response.statusCode).toBe(200);
155
+ expect(JSON.parse(response.payload)).toEqual({
156
+ ...mockState,
157
+ touched_at: mockState.touched_at.toISOString()
158
+ });
159
+ });
160
+ });
161
+ it('respects max queue depth', async () => {
162
+ const mockState = { started: true, ready: true, touched_at: new Date() };
163
+ vi.mocked(container.probes.state).mockReturnValue(mockState);
164
+ // Create array of 35 concurrent requests (default max_queue_depth is 20)
165
+ const requests = Array(35)
166
+ .fill(null)
167
+ .map(() => app.inject({
168
+ method: 'GET',
169
+ url: ProbeRoutes.STARTUP
170
+ }));
171
+ const responses = await Promise.all(requests);
172
+ // Some requests should succeed and some should fail with 429
173
+ const successCount = responses.filter((r) => r.statusCode === 200).length;
174
+ const queueFullCount = responses.filter((r) => r.statusCode === 429).length;
175
+ expect(successCount).toBeGreaterThan(0);
176
+ expect(queueFullCount).toBeGreaterThan(0);
177
+ expect(successCount + queueFullCount).toBe(35);
178
+ });
179
+ });
180
+ describe('Content Types', () => {
181
+ it('returns correct content type headers', async () => {
182
+ const mockState = { started: true, ready: true, touched_at: new Date() };
183
+ vi.mocked(container.probes.state).mockReturnValue(mockState);
184
+ const response = await app.inject({
185
+ method: 'GET',
186
+ url: ProbeRoutes.STARTUP
187
+ });
188
+ expect(response.headers['content-type']).toMatch(/application\/json/);
189
+ });
190
+ });
191
+ });
192
+ //# sourceMappingURL=probes.integration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"probes.integration.test.js","sourceRoot":"","sources":["../../src/routes/probes.integration.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,119 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { container } from '@powersync/lib-services-framework';
3
+ import { startupCheck, livenessCheck, readinessCheck } from '../../../src/routes/endpoints/probes.js';
4
+ // Mock the container
5
+ vi.mock('@powersync/lib-services-framework', () => ({
6
+ container: {
7
+ probes: {
8
+ state: vi.fn()
9
+ }
10
+ },
11
+ router: {
12
+ HTTPMethod: {
13
+ GET: 'GET'
14
+ },
15
+ RouterResponse: class RouterResponse {
16
+ status;
17
+ data;
18
+ headers;
19
+ afterSend;
20
+ __micro_router_response = true;
21
+ constructor({ status, data, headers, afterSend }) {
22
+ this.status = status || 200;
23
+ this.data = data;
24
+ this.headers = headers || { 'Content-Type': 'application/json' };
25
+ this.afterSend = afterSend ?? (() => Promise.resolve());
26
+ }
27
+ }
28
+ }
29
+ }));
30
+ describe('Probe Routes', () => {
31
+ beforeEach(() => {
32
+ vi.clearAllMocks();
33
+ });
34
+ describe('startupCheck', () => {
35
+ it('has the correct route definitions', () => {
36
+ expect(startupCheck.path).toBe('/probes/startup');
37
+ expect(startupCheck.method).toBe('GET');
38
+ });
39
+ it('returns 200 when started is true', async () => {
40
+ const mockState = {
41
+ started: true,
42
+ ready: true,
43
+ touched_at: new Date()
44
+ };
45
+ vi.mocked(container.probes.state).mockReturnValue(mockState);
46
+ const response = await startupCheck.handler();
47
+ expect(response.status).toEqual(200);
48
+ expect(response.data).toEqual(mockState);
49
+ });
50
+ it('returns 400 when started is false', async () => {
51
+ const mockState = {
52
+ started: false,
53
+ ready: false,
54
+ touched_at: new Date()
55
+ };
56
+ vi.mocked(container.probes.state).mockReturnValue(mockState);
57
+ const response = await startupCheck.handler();
58
+ expect(response.status).toBe(400);
59
+ expect(response.data).toEqual(mockState);
60
+ });
61
+ });
62
+ describe('livenessCheck', () => {
63
+ it('has the correct route definitions', () => {
64
+ expect(livenessCheck.path).toBe('/probes/liveness');
65
+ expect(livenessCheck.method).toBe('GET');
66
+ });
67
+ it('returns 200 when last touch was less than 10 seconds ago', async () => {
68
+ const mockState = {
69
+ started: true,
70
+ ready: true,
71
+ touched_at: new Date(Date.now() - 9000) // 11 seconds ago
72
+ };
73
+ vi.mocked(container.probes.state).mockReturnValue(mockState);
74
+ const response = await livenessCheck.handler();
75
+ expect(response.status).toBe(200);
76
+ expect(response.data).toEqual(mockState);
77
+ });
78
+ it('returns 400 when last touch was more than 10 seconds ago', async () => {
79
+ const mockState = {
80
+ started: true,
81
+ ready: true,
82
+ touched_at: new Date(Date.now() - 11000)
83
+ };
84
+ vi.mocked(container.probes.state).mockReturnValue(mockState);
85
+ const response = await livenessCheck.handler();
86
+ expect(response.status).toBe(400);
87
+ expect(response.data).toEqual(mockState);
88
+ });
89
+ });
90
+ describe('readinessCheck', () => {
91
+ it('has the correct route definitions', () => {
92
+ expect(readinessCheck.path).toBe('/probes/readiness');
93
+ expect(readinessCheck.method).toBe('GET');
94
+ });
95
+ it('returns 200 when ready is true', async () => {
96
+ const mockState = {
97
+ started: true,
98
+ ready: true,
99
+ touched_at: new Date()
100
+ };
101
+ vi.mocked(container.probes.state).mockReturnValue(mockState);
102
+ const response = await readinessCheck.handler();
103
+ expect(response.status).toBe(200);
104
+ expect(response.data).toEqual(mockState);
105
+ });
106
+ it('returns 400 when ready is false', async () => {
107
+ const mockState = {
108
+ started: true,
109
+ ready: false,
110
+ touched_at: new Date()
111
+ };
112
+ vi.mocked(container.probes.state).mockReturnValue(mockState);
113
+ const response = await readinessCheck.handler();
114
+ expect(response.status).toBe(400);
115
+ expect(response.data).toEqual(mockState);
116
+ });
117
+ });
118
+ });
119
+ //# sourceMappingURL=probes.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"probes.test.js","sourceRoot":"","sources":["../../src/routes/probes.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,7 @@
1
+ import { container } from '@powersync/lib-services-framework';
2
+ import { beforeAll } from 'vitest';
3
+ beforeAll(() => {
4
+ // Executes for every test file
5
+ container.registerDefaults();
6
+ });
7
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAEnC,SAAS,CAAC,GAAG,EAAE;IACb,+BAA+B;IAC/B,SAAS,CAAC,gBAAgB,EAAE,CAAC;AAC/B,CAAC,CAAC,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { OplogEntry } from '@/util/protocol-types.js';
2
+ export declare function putOp(table: string, data: Record<string, any>): Partial<OplogEntry>;
3
+ export declare function removeOp(table: string, id: string): Partial<OplogEntry>;
4
+ export declare function compareIds(a: OplogEntry, b: OplogEntry): number;
5
+ export declare function oneFromAsync<T>(source: Iterable<T> | AsyncIterable<T>): Promise<T>;
6
+ export declare function fromAsync<T>(source: Iterable<T> | AsyncIterable<T>): Promise<T[]>;
@@ -0,0 +1,37 @@
1
+ import { JSONBig } from '@powersync/service-jsonbig';
2
+ export function putOp(table, data) {
3
+ return {
4
+ op: 'PUT',
5
+ object_type: table,
6
+ object_id: data.id,
7
+ data: JSONBig.stringify(data)
8
+ };
9
+ }
10
+ export function removeOp(table, id) {
11
+ return {
12
+ op: 'REMOVE',
13
+ object_type: table,
14
+ object_id: id
15
+ };
16
+ }
17
+ export function compareIds(a, b) {
18
+ return a.object_id.localeCompare(b.object_id);
19
+ }
20
+ export async function oneFromAsync(source) {
21
+ const items = [];
22
+ for await (const item of source) {
23
+ items.push(item);
24
+ }
25
+ if (items.length != 1) {
26
+ throw new Error(`One item expected, got: ${items.length}`);
27
+ }
28
+ return items[0];
29
+ }
30
+ export async function fromAsync(source) {
31
+ const items = [];
32
+ for await (const item of source) {
33
+ items.push(item);
34
+ }
35
+ return items;
36
+ }
37
+ //# sourceMappingURL=stream_utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream_utils.js","sourceRoot":"","sources":["../src/stream_utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAErD,MAAM,UAAU,KAAK,CAAC,KAAa,EAAE,IAAyB;IAC5D,OAAO;QACL,EAAE,EAAE,KAAK;QACT,WAAW,EAAE,KAAK;QAClB,SAAS,EAAE,IAAI,CAAC,EAAE;QAClB,IAAI,EAAE,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC;KAC9B,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAAa,EAAE,EAAU;IAChD,OAAO;QACL,EAAE,EAAE,QAAQ;QACZ,WAAW,EAAE,KAAK;QAClB,SAAS,EAAE,EAAE;KACd,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,CAAa,EAAE,CAAa;IACrD,OAAO,CAAC,CAAC,SAAU,CAAC,aAAa,CAAC,CAAC,CAAC,SAAU,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAI,MAAsC;IAC1E,MAAM,KAAK,GAAQ,EAAE,CAAC;IACtB,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAChC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,2BAA2B,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAI,MAAsC;IACvE,MAAM,KAAK,GAAQ,EAAE,CAAC;IACtB,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAChC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1 @@
1
+ export {};