@signalium/query 1.0.13 → 1.0.15

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 (151) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/cjs/development/index.js +2994 -0
  3. package/dist/cjs/development/index.js.map +1 -0
  4. package/dist/cjs/development/react/index.js +52 -0
  5. package/dist/cjs/development/react/index.js.map +1 -0
  6. package/dist/cjs/{stores/shared.js → development/shared-5acOO-tS.js} +11 -14
  7. package/dist/cjs/development/shared-5acOO-tS.js.map +1 -0
  8. package/dist/cjs/development/stores/async.js +304 -0
  9. package/dist/cjs/development/stores/async.js.map +1 -0
  10. package/dist/cjs/development/stores/sync.js +214 -0
  11. package/dist/cjs/development/stores/sync.js.map +1 -0
  12. package/dist/cjs/production/index.js +2994 -0
  13. package/dist/cjs/production/index.js.map +1 -0
  14. package/dist/cjs/production/package.json +3 -0
  15. package/dist/cjs/production/react/index.js +52 -0
  16. package/dist/cjs/production/react/index.js.map +1 -0
  17. package/dist/cjs/production/shared-5acOO-tS.js +20 -0
  18. package/dist/cjs/production/shared-5acOO-tS.js.map +1 -0
  19. package/dist/cjs/production/stores/async.js +304 -0
  20. package/dist/cjs/production/stores/async.js.map +1 -0
  21. package/dist/cjs/production/stores/sync.js +214 -0
  22. package/dist/cjs/production/stores/sync.js.map +1 -0
  23. package/dist/esm/EntityMap.d.ts +22 -0
  24. package/dist/esm/EntityMap.d.ts.map +1 -1
  25. package/dist/esm/MutationResult.d.ts +43 -0
  26. package/dist/esm/MutationResult.d.ts.map +1 -0
  27. package/dist/esm/QueryClient.d.ts +31 -2
  28. package/dist/esm/QueryClient.d.ts.map +1 -1
  29. package/dist/esm/development/index.js +2994 -0
  30. package/dist/esm/development/index.js.map +1 -0
  31. package/dist/esm/development/react/index.js +52 -0
  32. package/dist/esm/development/react/index.js.map +1 -0
  33. package/dist/esm/development/shared-Br5plsKm.js +21 -0
  34. package/dist/esm/development/shared-Br5plsKm.js.map +1 -0
  35. package/dist/esm/development/stores/async.js +304 -0
  36. package/dist/esm/development/stores/async.js.map +1 -0
  37. package/dist/esm/development/stores/sync.js +214 -0
  38. package/dist/esm/development/stores/sync.js.map +1 -0
  39. package/dist/esm/index.d.ts +5 -0
  40. package/dist/esm/index.d.ts.map +1 -1
  41. package/dist/esm/mutation.d.ts +82 -0
  42. package/dist/esm/mutation.d.ts.map +1 -0
  43. package/dist/esm/parseEntities.d.ts.map +1 -1
  44. package/dist/esm/production/index.js +2994 -0
  45. package/dist/esm/production/index.js.map +1 -0
  46. package/dist/esm/production/react/index.js +52 -0
  47. package/dist/esm/production/react/index.js.map +1 -0
  48. package/dist/esm/production/shared-Br5plsKm.js +21 -0
  49. package/dist/esm/production/shared-Br5plsKm.js.map +1 -0
  50. package/dist/esm/production/stores/async.js +304 -0
  51. package/dist/esm/production/stores/async.js.map +1 -0
  52. package/dist/esm/production/stores/sync.js +214 -0
  53. package/dist/esm/production/stores/sync.js.map +1 -0
  54. package/dist/esm/proxy.d.ts +9 -6
  55. package/dist/esm/proxy.d.ts.map +1 -1
  56. package/dist/esm/query.d.ts +3 -1
  57. package/dist/esm/query.d.ts.map +1 -1
  58. package/dist/esm/typeDefs.d.ts +4 -2
  59. package/dist/esm/typeDefs.d.ts.map +1 -1
  60. package/dist/esm/types.d.ts +71 -4
  61. package/dist/esm/types.d.ts.map +1 -1
  62. package/dist/esm/utils.d.ts +35 -0
  63. package/dist/esm/utils.d.ts.map +1 -1
  64. package/package.json +55 -21
  65. package/stores/async.js +1 -1
  66. package/stores/sync.js +1 -1
  67. package/dist/cjs/EntityMap.js +0 -103
  68. package/dist/cjs/EntityMap.js.map +0 -1
  69. package/dist/cjs/MemoryEvictionManager.js +0 -56
  70. package/dist/cjs/MemoryEvictionManager.js.map +0 -1
  71. package/dist/cjs/NetworkManager.js +0 -125
  72. package/dist/cjs/NetworkManager.js.map +0 -1
  73. package/dist/cjs/QueryClient.js +0 -162
  74. package/dist/cjs/QueryClient.js.map +0 -1
  75. package/dist/cjs/QueryResult.js +0 -920
  76. package/dist/cjs/QueryResult.js.map +0 -1
  77. package/dist/cjs/RefetchManager.js +0 -88
  78. package/dist/cjs/RefetchManager.js.map +0 -1
  79. package/dist/cjs/errors.js +0 -129
  80. package/dist/cjs/errors.js.map +0 -1
  81. package/dist/cjs/index.js +0 -43
  82. package/dist/cjs/index.js.map +0 -1
  83. package/dist/cjs/parseEntities.js +0 -142
  84. package/dist/cjs/parseEntities.js.map +0 -1
  85. package/dist/cjs/pathInterpolator.js +0 -69
  86. package/dist/cjs/pathInterpolator.js.map +0 -1
  87. package/dist/cjs/proxy.js +0 -263
  88. package/dist/cjs/proxy.js.map +0 -1
  89. package/dist/cjs/query.js +0 -184
  90. package/dist/cjs/query.js.map +0 -1
  91. package/dist/cjs/react/index.js +0 -6
  92. package/dist/cjs/react/index.js.map +0 -1
  93. package/dist/cjs/react/use-query.js +0 -56
  94. package/dist/cjs/react/use-query.js.map +0 -1
  95. package/dist/cjs/stores/async.js +0 -344
  96. package/dist/cjs/stores/async.js.map +0 -1
  97. package/dist/cjs/stores/shared.js.map +0 -1
  98. package/dist/cjs/stores/sync.js +0 -240
  99. package/dist/cjs/stores/sync.js.map +0 -1
  100. package/dist/cjs/tsconfig.cjs.tsbuildinfo +0 -1
  101. package/dist/cjs/type-utils.js +0 -3
  102. package/dist/cjs/type-utils.js.map +0 -1
  103. package/dist/cjs/typeDefs.js +0 -620
  104. package/dist/cjs/typeDefs.js.map +0 -1
  105. package/dist/cjs/types.js +0 -33
  106. package/dist/cjs/types.js.map +0 -1
  107. package/dist/cjs/utils.js +0 -23
  108. package/dist/cjs/utils.js.map +0 -1
  109. package/dist/esm/EntityMap.js +0 -99
  110. package/dist/esm/EntityMap.js.map +0 -1
  111. package/dist/esm/MemoryEvictionManager.js +0 -51
  112. package/dist/esm/MemoryEvictionManager.js.map +0 -1
  113. package/dist/esm/NetworkManager.js +0 -120
  114. package/dist/esm/NetworkManager.js.map +0 -1
  115. package/dist/esm/QueryClient.js +0 -154
  116. package/dist/esm/QueryClient.js.map +0 -1
  117. package/dist/esm/QueryResult.js +0 -916
  118. package/dist/esm/QueryResult.js.map +0 -1
  119. package/dist/esm/RefetchManager.js +0 -83
  120. package/dist/esm/RefetchManager.js.map +0 -1
  121. package/dist/esm/errors.js +0 -125
  122. package/dist/esm/errors.js.map +0 -1
  123. package/dist/esm/index.js +0 -8
  124. package/dist/esm/index.js.map +0 -1
  125. package/dist/esm/parseEntities.js +0 -135
  126. package/dist/esm/parseEntities.js.map +0 -1
  127. package/dist/esm/pathInterpolator.js +0 -66
  128. package/dist/esm/pathInterpolator.js.map +0 -1
  129. package/dist/esm/proxy.js +0 -254
  130. package/dist/esm/proxy.js.map +0 -1
  131. package/dist/esm/query.js +0 -177
  132. package/dist/esm/query.js.map +0 -1
  133. package/dist/esm/react/index.js +0 -2
  134. package/dist/esm/react/index.js.map +0 -1
  135. package/dist/esm/react/use-query.js +0 -53
  136. package/dist/esm/react/use-query.js.map +0 -1
  137. package/dist/esm/stores/async.js +0 -340
  138. package/dist/esm/stores/async.js.map +0 -1
  139. package/dist/esm/stores/shared.js +0 -13
  140. package/dist/esm/stores/shared.js.map +0 -1
  141. package/dist/esm/stores/sync.js +0 -234
  142. package/dist/esm/stores/sync.js.map +0 -1
  143. package/dist/esm/type-utils.js +0 -2
  144. package/dist/esm/type-utils.js.map +0 -1
  145. package/dist/esm/typeDefs.js +0 -606
  146. package/dist/esm/typeDefs.js.map +0 -1
  147. package/dist/esm/types.js +0 -30
  148. package/dist/esm/types.js.map +0 -1
  149. package/dist/esm/utils.js +0 -20
  150. package/dist/esm/utils.js.map +0 -1
  151. /package/dist/cjs/{package.json → development/package.json} +0 -0
@@ -0,0 +1,52 @@
1
+ import { useReactive } from "signalium/react";
2
+ import { reactive } from "signalium";
3
+ function cloneDeep(value) {
4
+ if (Array.isArray(value)) {
5
+ return value.map(cloneDeep);
6
+ }
7
+ if (value && typeof value === "object") {
8
+ if (value instanceof Date) {
9
+ return new Date(value);
10
+ }
11
+ if (value instanceof RegExp) {
12
+ return new RegExp(value);
13
+ }
14
+ if (value instanceof Map) {
15
+ return new Map(Array.from(value.entries()).map(([k, v]) => [cloneDeep(k), cloneDeep(v)]));
16
+ }
17
+ if (value instanceof Set) {
18
+ return new Set(Array.from(value).map(cloneDeep));
19
+ }
20
+ const result = Object.create(Object.getPrototypeOf(value));
21
+ for (const key of Object.keys(value)) {
22
+ result[key] = cloneDeep(value[key]);
23
+ }
24
+ return result;
25
+ }
26
+ return value;
27
+ }
28
+ const clonedResult = reactive(
29
+ (result) => cloneDeep(result.value)
30
+ );
31
+ const riefiedQuery = reactive(
32
+ (fn, ...args) => {
33
+ const queryResult = fn(...args);
34
+ return new Proxy(queryResult, {
35
+ get(target, prop, receiver) {
36
+ if (prop === "value") {
37
+ return clonedResult(target);
38
+ }
39
+ return Reflect.get(target, prop, receiver);
40
+ }
41
+ });
42
+ }
43
+ );
44
+ function useQuery(fn, ...args) {
45
+ const result = useReactive(riefiedQuery, fn, ...args);
46
+ useReactive(() => result.value);
47
+ return result;
48
+ }
49
+ export {
50
+ useQuery
51
+ };
52
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../../../src/react/use-query.ts"],"sourcesContent":["import { useReactive } from 'signalium/react';\nimport { reactive } from 'signalium';\nimport { QueryResult, InfiniteQueryResult, StreamQueryResult } from '../types.js';\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\ntype Narrowable = string | number | boolean | null | undefined | bigint | symbol | {};\n\nfunction cloneDeep<T>(value: T): T {\n if (Array.isArray(value)) {\n return value.map(cloneDeep) as unknown as T;\n }\n if (value && typeof value === 'object') {\n // Handle Date\n if (value instanceof Date) {\n return new Date(value) as unknown as T;\n }\n // Handle RegExp\n if (value instanceof RegExp) {\n return new RegExp(value) as unknown as T;\n }\n // Handle Map\n if (value instanceof Map) {\n return new Map(Array.from(value.entries()).map(([k, v]) => [cloneDeep(k), cloneDeep(v)])) as unknown as T;\n }\n // Handle Set\n if (value instanceof Set) {\n return new Set(Array.from(value).map(cloneDeep)) as unknown as T;\n }\n // Handle plain objects\n const result: any = Object.create(Object.getPrototypeOf(value));\n for (const key of Object.keys(value)) {\n result[key] = cloneDeep((value as any)[key]);\n }\n return result as T;\n }\n return value;\n}\n\nconst clonedResult = reactive(\n (\n result:\n | QueryResult<unknown, unknown, unknown>\n | InfiniteQueryResult<unknown, unknown, unknown>\n | StreamQueryResult<unknown>,\n ) => cloneDeep(result.value),\n);\n\nconst riefiedQuery = reactive(\n <R, Args extends readonly Narrowable[]>(\n fn: (\n ...args: Args\n ) => QueryResult<R, unknown, unknown> | InfiniteQueryResult<R, unknown, unknown> | StreamQueryResult<R>,\n ...args: Args\n ): QueryResult<R, unknown, unknown> | InfiniteQueryResult<R, unknown, unknown> | StreamQueryResult<R> => {\n const queryResult = fn(...args);\n\n return new Proxy(queryResult, {\n get(target, prop, receiver) {\n // Clone the value property when accessed\n if (prop === 'value') {\n return clonedResult(target);\n }\n\n // Forward all other properties/methods to the original query result\n return Reflect.get(target, prop, receiver);\n },\n });\n },\n);\n\n// Overload for standard query\nexport function useQuery<R, StreamType, OptimisticUpdateType, Args extends readonly Narrowable[]>(\n fn: (...args: Args) => QueryResult<R, StreamType, OptimisticUpdateType>,\n ...args: Args\n): QueryResult<R, StreamType, OptimisticUpdateType>;\n\n// Overload for infinite query\nexport function useQuery<R, StreamType, OptimisticUpdateType, Args extends readonly Narrowable[]>(\n fn: (...args: Args) => InfiniteQueryResult<R, StreamType, OptimisticUpdateType>,\n ...args: Args\n): InfiniteQueryResult<R, StreamType, OptimisticUpdateType>;\n\n// Overload for stream query\nexport function useQuery<R, Args extends readonly Narrowable[]>(\n fn: (...args: Args) => StreamQueryResult<R>,\n ...args: Args\n): StreamQueryResult<R>;\n\n// Implementation\nexport function useQuery<R, StreamType, OptimisticUpdateType, Args extends readonly Narrowable[]>(\n fn: (\n ...args: Args\n ) =>\n | QueryResult<R, StreamType, OptimisticUpdateType>\n | InfiniteQueryResult<R, StreamType, OptimisticUpdateType>\n | StreamQueryResult<R>,\n ...args: Args\n):\n | QueryResult<R, StreamType, OptimisticUpdateType>\n | InfiniteQueryResult<R, StreamType, OptimisticUpdateType>\n | StreamQueryResult<R> {\n const result = useReactive(riefiedQuery, fn, ...args) as\n | QueryResult<R, StreamType, OptimisticUpdateType>\n | InfiniteQueryResult<R, StreamType, OptimisticUpdateType>\n | StreamQueryResult<R>;\n\n useReactive(() => result.value);\n\n return result;\n}\n"],"names":[],"mappings":";;AAOA,SAAS,UAAa,OAAa;AACjC,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,IAAI,SAAS;AAAA,EAC5B;AACA,MAAI,SAAS,OAAO,UAAU,UAAU;AAEtC,QAAI,iBAAiB,MAAM;AACzB,aAAO,IAAI,KAAK,KAAK;AAAA,IACvB;AAEA,QAAI,iBAAiB,QAAQ;AAC3B,aAAO,IAAI,OAAO,KAAK;AAAA,IACzB;AAEA,QAAI,iBAAiB,KAAK;AACxB,aAAO,IAAI,IAAI,MAAM,KAAK,MAAM,QAAA,CAAS,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;AAAA,IAC1F;AAEA,QAAI,iBAAiB,KAAK;AACxB,aAAO,IAAI,IAAI,MAAM,KAAK,KAAK,EAAE,IAAI,SAAS,CAAC;AAAA,IACjD;AAEA,UAAM,SAAc,OAAO,OAAO,OAAO,eAAe,KAAK,CAAC;AAC9D,eAAW,OAAO,OAAO,KAAK,KAAK,GAAG;AACpC,aAAO,GAAG,IAAI,UAAW,MAAc,GAAG,CAAC;AAAA,IAC7C;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,MAAM,eAAe;AAAA,EACnB,CACE,WAIG,UAAU,OAAO,KAAK;AAC7B;AAEA,MAAM,eAAe;AAAA,EACnB,CACE,OAGG,SACoG;AACvG,UAAM,cAAc,GAAG,GAAG,IAAI;AAE9B,WAAO,IAAI,MAAM,aAAa;AAAA,MAC5B,IAAI,QAAQ,MAAM,UAAU;AAE1B,YAAI,SAAS,SAAS;AACpB,iBAAO,aAAa,MAAM;AAAA,QAC5B;AAGA,eAAO,QAAQ,IAAI,QAAQ,MAAM,QAAQ;AAAA,MAC3C;AAAA,IAAA,CACD;AAAA,EACH;AACF;AAqBO,SAAS,SACd,OAMG,MAIoB;AACvB,QAAM,SAAS,YAAY,cAAc,IAAI,GAAG,IAAI;AAKpD,cAAY,MAAM,OAAO,KAAK;AAE9B,SAAO;AACT;"}
@@ -0,0 +1,21 @@
1
+ const valueKeyFor = (id) => `sq:doc:value:${id}`;
2
+ const refCountKeyFor = (id) => `sq:doc:refCount:${id}`;
3
+ const refIdsKeyFor = (id) => `sq:doc:refIds:${id}`;
4
+ const updatedAtKeyFor = (id) => `sq:doc:updatedAt:${id}`;
5
+ const streamOrphanRefsKeyFor = (id) => `sq:doc:streamOrphanRefs:${id}`;
6
+ const optimisticInsertRefsKeyFor = (id) => `sq:doc:optimisticInsertRefs:${id}`;
7
+ const queueKeyFor = (queryDefId) => `sq:doc:queue:${queryDefId}`;
8
+ const DEFAULT_MAX_COUNT = 50;
9
+ const DEFAULT_GC_TIME = 1e3 * 60 * 60 * 24;
10
+ export {
11
+ DEFAULT_GC_TIME as D,
12
+ DEFAULT_MAX_COUNT as a,
13
+ refCountKeyFor as b,
14
+ optimisticInsertRefsKeyFor as o,
15
+ queueKeyFor as q,
16
+ refIdsKeyFor as r,
17
+ streamOrphanRefsKeyFor as s,
18
+ updatedAtKeyFor as u,
19
+ valueKeyFor as v
20
+ };
21
+ //# sourceMappingURL=shared-Br5plsKm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared-Br5plsKm.js","sources":["../../../src/stores/shared.ts"],"sourcesContent":["// Query Instance keys\nexport const valueKeyFor = (id: number) => `sq:doc:value:${id}`;\nexport const refCountKeyFor = (id: number) => `sq:doc:refCount:${id}`;\nexport const refIdsKeyFor = (id: number) => `sq:doc:refIds:${id}`;\nexport const updatedAtKeyFor = (id: number) => `sq:doc:updatedAt:${id}`;\nexport const streamOrphanRefsKeyFor = (id: number) => `sq:doc:streamOrphanRefs:${id}`;\nexport const optimisticInsertRefsKeyFor = (id: number) => `sq:doc:optimisticInsertRefs:${id}`;\n\n// Query Type keys\nexport const queueKeyFor = (queryDefId: string) => `sq:doc:queue:${queryDefId}`;\n\n// Default values\nexport const DEFAULT_MAX_COUNT = 50;\nexport const DEFAULT_GC_TIME = 1000 * 60 * 60 * 24; // 24 hours\n"],"names":[],"mappings":"AACO,MAAM,cAAc,CAAC,OAAe,gBAAgB,EAAE;AACtD,MAAM,iBAAiB,CAAC,OAAe,mBAAmB,EAAE;AAC5D,MAAM,eAAe,CAAC,OAAe,iBAAiB,EAAE;AACxD,MAAM,kBAAkB,CAAC,OAAe,oBAAoB,EAAE;AAC9D,MAAM,yBAAyB,CAAC,OAAe,2BAA2B,EAAE;AAC5E,MAAM,6BAA6B,CAAC,OAAe,+BAA+B,EAAE;AAGpF,MAAM,cAAc,CAAC,eAAuB,gBAAgB,UAAU;AAGtE,MAAM,oBAAoB;AAC1B,MAAM,kBAAkB,MAAO,KAAK,KAAK;"}
@@ -0,0 +1,304 @@
1
+ import { u as updatedAtKeyFor, D as DEFAULT_GC_TIME, v as valueKeyFor, r as refIdsKeyFor, s as streamOrphanRefsKeyFor, o as optimisticInsertRefsKeyFor, q as queueKeyFor, a as DEFAULT_MAX_COUNT, b as refCountKeyFor } from "../shared-Br5plsKm.js";
2
+ class AsyncQueryStore {
3
+ isWriter;
4
+ delegate;
5
+ sendMessage;
6
+ messageQueue = [];
7
+ queues = /* @__PURE__ */ new Map();
8
+ queueProcessorPromise;
9
+ resolveQueueWait;
10
+ constructor(config) {
11
+ this.isWriter = config.isWriter;
12
+ this.delegate = config.delegate;
13
+ const { sendMessage } = config.connect(this.handleMessage.bind(this));
14
+ this.sendMessage = sendMessage;
15
+ if (this.isWriter) {
16
+ if (!this.delegate) {
17
+ throw new Error("Writer must have a delegate");
18
+ }
19
+ this.startQueueProcessor();
20
+ }
21
+ }
22
+ handleMessage(msg) {
23
+ if (this.isWriter) {
24
+ this.enqueueMessage(msg);
25
+ }
26
+ }
27
+ enqueueMessage(msg) {
28
+ this.messageQueue.push(msg);
29
+ if (this.resolveQueueWait) {
30
+ this.resolveQueueWait();
31
+ this.resolveQueueWait = void 0;
32
+ }
33
+ }
34
+ startQueueProcessor() {
35
+ this.queueProcessorPromise = this.processQueue();
36
+ }
37
+ async processQueue() {
38
+ while (true) {
39
+ while (this.messageQueue.length === 0) {
40
+ await new Promise((resolve) => {
41
+ this.resolveQueueWait = resolve;
42
+ });
43
+ }
44
+ const msg = this.messageQueue.shift();
45
+ try {
46
+ await this.processMessage(msg);
47
+ } catch (error) {
48
+ console.error("Error processing message:", error);
49
+ }
50
+ }
51
+ }
52
+ async processMessage(msg) {
53
+ switch (msg.type) {
54
+ case "saveQuery":
55
+ await this.writerSaveQuery(msg.queryDefId, msg.queryKey, msg.value, msg.updatedAt, msg.refIds, msg.extra);
56
+ break;
57
+ case "saveEntity":
58
+ await this.writerSaveEntity(msg.entityKey, msg.value, msg.refIds);
59
+ break;
60
+ case "activateQuery":
61
+ await this.writerActivateQuery(msg.queryDefId, msg.queryKey);
62
+ break;
63
+ case "deleteQuery":
64
+ await this.writerDeleteValue(msg.queryKey);
65
+ break;
66
+ }
67
+ }
68
+ async loadQuery(queryDef, queryKey, entityMap) {
69
+ if (!this.delegate) {
70
+ return void 0;
71
+ }
72
+ const updatedAt = await this.delegate.getNumber(updatedAtKeyFor(queryKey));
73
+ if (updatedAt === void 0 || updatedAt < Date.now() - (queryDef.cache?.gcTime ?? DEFAULT_GC_TIME)) {
74
+ return void 0;
75
+ }
76
+ const valueStr = await this.delegate.getString(valueKeyFor(queryKey));
77
+ if (valueStr === void 0) {
78
+ return void 0;
79
+ }
80
+ const entityIds = await this.delegate.getBuffer(refIdsKeyFor(queryKey));
81
+ if (entityIds !== void 0) {
82
+ await this.preloadEntities(entityIds, entityMap);
83
+ }
84
+ const streamOrphanRefs = await this.delegate.getBuffer(streamOrphanRefsKeyFor(queryKey));
85
+ const optimisticInsertRefs = await this.delegate.getBuffer(optimisticInsertRefsKeyFor(queryKey));
86
+ if (streamOrphanRefs !== void 0) {
87
+ await this.preloadEntities(streamOrphanRefs, entityMap);
88
+ }
89
+ if (optimisticInsertRefs !== void 0) {
90
+ await this.preloadEntities(optimisticInsertRefs, entityMap);
91
+ }
92
+ let extra;
93
+ if (streamOrphanRefs !== void 0 || optimisticInsertRefs !== void 0) {
94
+ extra = {};
95
+ if (streamOrphanRefs !== void 0) {
96
+ extra.streamOrphanRefs = Array.from(streamOrphanRefs);
97
+ }
98
+ if (optimisticInsertRefs !== void 0) {
99
+ extra.optimisticInsertRefs = Array.from(optimisticInsertRefs);
100
+ }
101
+ }
102
+ this.activateQuery(queryDef, queryKey);
103
+ return {
104
+ value: JSON.parse(valueStr),
105
+ refIds: entityIds === void 0 ? void 0 : new Set(entityIds ?? []),
106
+ updatedAt,
107
+ extra
108
+ };
109
+ }
110
+ async preloadEntities(entityIds, entityMap) {
111
+ if (!this.delegate) {
112
+ return;
113
+ }
114
+ for (const entityId of entityIds) {
115
+ const entityValue = await this.delegate.getString(valueKeyFor(entityId));
116
+ if (entityValue === void 0) {
117
+ continue;
118
+ }
119
+ const entity = JSON.parse(entityValue);
120
+ entityMap.setPreloadedEntity(entityId, entity);
121
+ const childIds = await this.delegate.getBuffer(refIdsKeyFor(entityId));
122
+ if (childIds === void 0) {
123
+ continue;
124
+ }
125
+ await this.preloadEntities(childIds, entityMap);
126
+ }
127
+ }
128
+ saveQuery(queryDef, queryKey, value, updatedAt, refIds, extra) {
129
+ const message = {
130
+ type: "saveQuery",
131
+ queryDefId: queryDef.id,
132
+ queryKey,
133
+ value,
134
+ updatedAt,
135
+ refIds: refIds ? Array.from(refIds) : void 0,
136
+ extra
137
+ };
138
+ if (this.isWriter) {
139
+ this.enqueueMessage(message);
140
+ } else {
141
+ this.sendMessage(message);
142
+ }
143
+ }
144
+ saveEntity(entityKey, value, refIds) {
145
+ const message = {
146
+ type: "saveEntity",
147
+ entityKey,
148
+ value,
149
+ refIds: refIds ? Array.from(refIds) : void 0
150
+ };
151
+ if (this.isWriter) {
152
+ this.enqueueMessage(message);
153
+ } else {
154
+ this.sendMessage(message);
155
+ }
156
+ }
157
+ activateQuery(queryDef, queryKey) {
158
+ const message = {
159
+ type: "activateQuery",
160
+ queryDefId: queryDef.id,
161
+ queryKey
162
+ };
163
+ if (this.isWriter) {
164
+ this.enqueueMessage(message);
165
+ } else {
166
+ this.sendMessage(message);
167
+ }
168
+ }
169
+ deleteQuery(queryKey) {
170
+ const message = {
171
+ type: "deleteQuery",
172
+ queryKey
173
+ };
174
+ if (this.isWriter) {
175
+ this.enqueueMessage(message);
176
+ } else {
177
+ this.sendMessage(message);
178
+ }
179
+ }
180
+ // Writer-specific methods below
181
+ async writerSaveQuery(queryDefId, queryKey, value, updatedAt, refIds, extra) {
182
+ await this.setValue(queryKey, value, refIds ? new Set(refIds) : void 0);
183
+ await this.delegate.setNumber(updatedAtKeyFor(queryKey), updatedAt);
184
+ if (extra?.streamOrphanRefs !== void 0 && extra.streamOrphanRefs.length > 0) {
185
+ await this.delegate.setBuffer(streamOrphanRefsKeyFor(queryKey), new Uint32Array(extra.streamOrphanRefs));
186
+ } else {
187
+ await this.delegate.delete(streamOrphanRefsKeyFor(queryKey));
188
+ }
189
+ if (extra?.optimisticInsertRefs !== void 0 && extra.optimisticInsertRefs.length > 0) {
190
+ await this.delegate.setBuffer(optimisticInsertRefsKeyFor(queryKey), new Uint32Array(extra.optimisticInsertRefs));
191
+ } else {
192
+ await this.delegate.delete(optimisticInsertRefsKeyFor(queryKey));
193
+ }
194
+ await this.writerActivateQuery(queryDefId, queryKey);
195
+ }
196
+ async writerSaveEntity(entityKey, value, refIds) {
197
+ await this.setValue(entityKey, value, refIds ? new Set(refIds) : void 0);
198
+ }
199
+ async writerActivateQuery(queryDefId, queryKey) {
200
+ if (!await this.delegate.has(valueKeyFor(queryKey))) {
201
+ return;
202
+ }
203
+ let queue = this.queues.get(queryDefId);
204
+ if (queue === void 0) {
205
+ const maxCount = DEFAULT_MAX_COUNT;
206
+ queue = await this.delegate.getBuffer(queueKeyFor(queryDefId));
207
+ if (queue === void 0) {
208
+ queue = new Uint32Array(maxCount);
209
+ await this.delegate.setBuffer(queueKeyFor(queryDefId), queue);
210
+ } else if (queue.length !== maxCount) {
211
+ queue = new Uint32Array(queue.buffer, 0, maxCount);
212
+ await this.delegate.setBuffer(queueKeyFor(queryDefId), queue);
213
+ }
214
+ this.queues.set(queryDefId, queue);
215
+ }
216
+ const indexOfKey = queue.indexOf(queryKey);
217
+ if (indexOfKey >= 0) {
218
+ if (indexOfKey === 0) {
219
+ return;
220
+ }
221
+ queue.copyWithin(1, 0, indexOfKey);
222
+ queue[0] = queryKey;
223
+ return;
224
+ }
225
+ const evicted = queue[queue.length - 1];
226
+ queue.copyWithin(1, 0, queue.length - 1);
227
+ queue[0] = queryKey;
228
+ if (evicted !== 0) {
229
+ await this.writerDeleteValue(evicted);
230
+ await this.delegate.delete(updatedAtKeyFor(evicted));
231
+ }
232
+ }
233
+ async setValue(id, value, refIds) {
234
+ const delegate = this.delegate;
235
+ await delegate.setString(valueKeyFor(id), JSON.stringify(value));
236
+ const refIdsKey = refIdsKeyFor(id);
237
+ const prevRefIds = await delegate.getBuffer(refIdsKey);
238
+ if (refIds === void 0 || refIds.size === 0) {
239
+ await delegate.delete(refIdsKey);
240
+ if (prevRefIds !== void 0) {
241
+ for (let i = 0; i < prevRefIds.length; i++) {
242
+ const refId = prevRefIds[i];
243
+ await this.decrementRefCount(refId);
244
+ }
245
+ }
246
+ } else {
247
+ const newRefIds = new Uint32Array(refIds);
248
+ if (prevRefIds !== void 0) {
249
+ for (let i = 0; i < prevRefIds.length; i++) {
250
+ const refId = prevRefIds[i];
251
+ if (refIds.has(refId)) {
252
+ refIds.delete(refId);
253
+ } else {
254
+ await this.decrementRefCount(refId);
255
+ }
256
+ }
257
+ }
258
+ for (const refId of refIds) {
259
+ await this.incrementRefCount(refId);
260
+ }
261
+ await delegate.setBuffer(refIdsKey, newRefIds);
262
+ }
263
+ }
264
+ async writerDeleteValue(id) {
265
+ const delegate = this.delegate;
266
+ await delegate.delete(valueKeyFor(id));
267
+ await delegate.delete(refCountKeyFor(id));
268
+ const refIds = await delegate.getBuffer(refIdsKeyFor(id));
269
+ await delegate.delete(refIdsKeyFor(id));
270
+ if (refIds === void 0) {
271
+ return;
272
+ }
273
+ for (const refId of refIds) {
274
+ if (refId !== 0) {
275
+ await this.decrementRefCount(refId);
276
+ }
277
+ }
278
+ }
279
+ async incrementRefCount(refId) {
280
+ const delegate = this.delegate;
281
+ const refCountKey = refCountKeyFor(refId);
282
+ const currentCount = await delegate.getNumber(refCountKey) ?? 0;
283
+ const newCount = currentCount + 1;
284
+ await delegate.setNumber(refCountKey, newCount);
285
+ }
286
+ async decrementRefCount(refId) {
287
+ const delegate = this.delegate;
288
+ const refCountKey = refCountKeyFor(refId);
289
+ const currentCount = await delegate.getNumber(refCountKey);
290
+ if (currentCount === void 0) {
291
+ return;
292
+ }
293
+ const newCount = currentCount - 1;
294
+ if (newCount === 0) {
295
+ await this.writerDeleteValue(refId);
296
+ } else {
297
+ await delegate.setNumber(refCountKey, newCount);
298
+ }
299
+ }
300
+ }
301
+ export {
302
+ AsyncQueryStore
303
+ };
304
+ //# sourceMappingURL=async.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async.js","sources":["../../../../src/stores/async.ts"],"sourcesContent":["import { EntityStore } from '../EntityMap.js';\nimport { CachedQuery, CachedQueryExtra, QueryDefinition, QueryStore } from '../QueryClient.js';\nimport {\n DEFAULT_GC_TIME,\n DEFAULT_MAX_COUNT,\n optimisticInsertRefsKeyFor,\n queueKeyFor,\n refCountKeyFor,\n refIdsKeyFor,\n streamOrphanRefsKeyFor,\n updatedAtKeyFor,\n valueKeyFor,\n} from './shared.js';\n\n// -----------------------------------------------------------------------------\n// Async QueryStore Interfaces\n// -----------------------------------------------------------------------------\n\nexport interface AsyncPersistentStore {\n has(key: string): Promise<boolean>;\n\n getString(key: string): Promise<string | undefined>;\n setString(key: string, value: string): Promise<void>;\n\n getNumber(key: string): Promise<number | undefined>;\n setNumber(key: string, value: number): Promise<void>;\n\n getBuffer(key: string): Promise<Uint32Array | undefined>;\n setBuffer(key: string, value: Uint32Array): Promise<void>;\n\n delete(key: string): Promise<void>;\n}\n\nexport type StoreMessage =\n | {\n type: 'saveQuery';\n queryDefId: string;\n queryKey: number;\n value: unknown;\n updatedAt: number;\n refIds?: number[];\n extra?: CachedQueryExtra;\n }\n | { type: 'saveEntity'; entityKey: number; value: unknown; refIds?: number[] }\n | { type: 'activateQuery'; queryDefId: string; queryKey: number }\n | { type: 'deleteQuery'; queryKey: number };\n\nexport interface AsyncQueryStoreConfig {\n isWriter: boolean;\n connect: (handleMessage: (msg: StoreMessage) => void) => {\n sendMessage: (msg: StoreMessage) => void;\n };\n delegate?: AsyncPersistentStore; // Only provided for writer\n}\n// -----------------------------------------------------------------------------\n// Async QueryStore Implementation\n// -----------------------------------------------------------------------------\n\nexport class AsyncQueryStore implements QueryStore {\n private readonly isWriter: boolean;\n private readonly delegate?: AsyncPersistentStore;\n private readonly sendMessage: (msg: StoreMessage) => void;\n private readonly messageQueue: StoreMessage[] = [];\n private readonly queues: Map<string, Uint32Array> = new Map();\n private queueProcessorPromise?: Promise<void>;\n private resolveQueueWait?: () => void;\n\n constructor(config: AsyncQueryStoreConfig) {\n this.isWriter = config.isWriter;\n this.delegate = config.delegate;\n\n // Connect and get sendMessage function\n const { sendMessage } = config.connect(this.handleMessage.bind(this));\n this.sendMessage = sendMessage;\n\n // Start queue processor if this is a writer\n if (this.isWriter) {\n if (!this.delegate) {\n throw new Error('Writer must have a delegate');\n }\n this.startQueueProcessor();\n }\n }\n\n private handleMessage(msg: StoreMessage): void {\n if (this.isWriter) {\n // Enqueue the message for serial processing\n this.enqueueMessage(msg);\n }\n // Readers don't handle incoming messages\n }\n\n private enqueueMessage(msg: StoreMessage): void {\n this.messageQueue.push(msg);\n // Wake up the queue processor if it's waiting\n if (this.resolveQueueWait) {\n this.resolveQueueWait();\n this.resolveQueueWait = undefined;\n }\n }\n\n private startQueueProcessor(): void {\n this.queueProcessorPromise = this.processQueue();\n }\n\n private async processQueue(): Promise<void> {\n while (true) {\n // Wait for messages if queue is empty\n while (this.messageQueue.length === 0) {\n await new Promise<void>(resolve => {\n this.resolveQueueWait = resolve;\n });\n }\n\n // Process one message at a time\n const msg = this.messageQueue.shift()!;\n\n try {\n await this.processMessage(msg);\n } catch (error) {\n console.error('Error processing message:', error);\n }\n }\n }\n\n private async processMessage(msg: StoreMessage): Promise<void> {\n switch (msg.type) {\n case 'saveQuery':\n await this.writerSaveQuery(msg.queryDefId, msg.queryKey, msg.value, msg.updatedAt, msg.refIds, msg.extra);\n break;\n case 'saveEntity':\n await this.writerSaveEntity(msg.entityKey, msg.value, msg.refIds);\n break;\n case 'activateQuery':\n await this.writerActivateQuery(msg.queryDefId, msg.queryKey);\n break;\n case 'deleteQuery':\n await this.writerDeleteValue(msg.queryKey);\n break;\n }\n }\n\n async loadQuery(\n queryDef: QueryDefinition<any, any, any>,\n queryKey: number,\n entityMap: EntityStore,\n ): Promise<CachedQuery | undefined> {\n if (!this.delegate) {\n return undefined;\n }\n\n const updatedAt = await this.delegate.getNumber(updatedAtKeyFor(queryKey));\n\n if (updatedAt === undefined || updatedAt < Date.now() - (queryDef.cache?.gcTime ?? DEFAULT_GC_TIME)) {\n return undefined;\n }\n\n const valueStr = await this.delegate.getString(valueKeyFor(queryKey));\n\n if (valueStr === undefined) {\n return undefined;\n }\n\n const entityIds = await this.delegate.getBuffer(refIdsKeyFor(queryKey));\n\n if (entityIds !== undefined) {\n await this.preloadEntities(entityIds, entityMap);\n }\n\n // Load extra data (stream orphans and optimistic inserts)\n const streamOrphanRefs = await this.delegate.getBuffer(streamOrphanRefsKeyFor(queryKey));\n const optimisticInsertRefs = await this.delegate.getBuffer(optimisticInsertRefsKeyFor(queryKey));\n\n // Preload entities for extra data\n if (streamOrphanRefs !== undefined) {\n await this.preloadEntities(streamOrphanRefs, entityMap);\n }\n if (optimisticInsertRefs !== undefined) {\n await this.preloadEntities(optimisticInsertRefs, entityMap);\n }\n\n let extra: CachedQueryExtra | undefined;\n if (streamOrphanRefs !== undefined || optimisticInsertRefs !== undefined) {\n extra = {};\n if (streamOrphanRefs !== undefined) {\n extra.streamOrphanRefs = Array.from(streamOrphanRefs);\n }\n if (optimisticInsertRefs !== undefined) {\n extra.optimisticInsertRefs = Array.from(optimisticInsertRefs);\n }\n }\n\n this.activateQuery(queryDef, queryKey);\n\n return {\n value: JSON.parse(valueStr) as Record<string, unknown>,\n refIds: entityIds === undefined ? undefined : new Set(entityIds ?? []),\n updatedAt,\n extra,\n };\n }\n\n private async preloadEntities(entityIds: Uint32Array, entityMap: EntityStore): Promise<void> {\n if (!this.delegate) {\n return;\n }\n\n for (const entityId of entityIds) {\n const entityValue = await this.delegate.getString(valueKeyFor(entityId));\n\n if (entityValue === undefined) {\n continue;\n }\n\n const entity = JSON.parse(entityValue) as Record<string, unknown>;\n entityMap.setPreloadedEntity(entityId, entity);\n\n const childIds = await this.delegate.getBuffer(refIdsKeyFor(entityId));\n\n if (childIds === undefined) {\n continue;\n }\n\n await this.preloadEntities(childIds, entityMap);\n }\n }\n\n saveQuery(\n queryDef: QueryDefinition<any, any, any>,\n queryKey: number,\n value: unknown,\n updatedAt: number,\n refIds?: Set<number>,\n extra?: CachedQueryExtra,\n ): void {\n const message: StoreMessage = {\n type: 'saveQuery',\n queryDefId: queryDef.id,\n queryKey,\n value,\n updatedAt,\n refIds: refIds ? Array.from(refIds) : undefined,\n extra,\n };\n\n if (this.isWriter) {\n this.enqueueMessage(message);\n } else {\n this.sendMessage(message);\n }\n }\n\n saveEntity(entityKey: number, value: unknown, refIds?: Set<number>): void {\n const message: StoreMessage = {\n type: 'saveEntity',\n entityKey,\n value,\n refIds: refIds ? Array.from(refIds) : undefined,\n };\n\n if (this.isWriter) {\n this.enqueueMessage(message);\n } else {\n this.sendMessage(message);\n }\n }\n\n activateQuery(queryDef: QueryDefinition<any, any, any>, queryKey: number): void {\n const message: StoreMessage = {\n type: 'activateQuery',\n queryDefId: queryDef.id,\n queryKey,\n };\n\n if (this.isWriter) {\n this.enqueueMessage(message);\n } else {\n this.sendMessage(message);\n }\n }\n\n deleteQuery(queryKey: number): void {\n const message: StoreMessage = {\n type: 'deleteQuery',\n queryKey,\n };\n\n if (this.isWriter) {\n this.enqueueMessage(message);\n } else {\n this.sendMessage(message);\n }\n }\n\n // Writer-specific methods below\n\n private async writerSaveQuery(\n queryDefId: string,\n queryKey: number,\n value: unknown,\n updatedAt: number,\n refIds?: number[],\n extra?: CachedQueryExtra,\n ): Promise<void> {\n await this.setValue(queryKey, value, refIds ? new Set(refIds) : undefined);\n await this.delegate!.setNumber(updatedAtKeyFor(queryKey), updatedAt);\n\n // Save extra data\n if (extra?.streamOrphanRefs !== undefined && extra.streamOrphanRefs.length > 0) {\n await this.delegate!.setBuffer(streamOrphanRefsKeyFor(queryKey), new Uint32Array(extra.streamOrphanRefs));\n } else {\n await this.delegate!.delete(streamOrphanRefsKeyFor(queryKey));\n }\n\n if (extra?.optimisticInsertRefs !== undefined && extra.optimisticInsertRefs.length > 0) {\n await this.delegate!.setBuffer(optimisticInsertRefsKeyFor(queryKey), new Uint32Array(extra.optimisticInsertRefs));\n } else {\n await this.delegate!.delete(optimisticInsertRefsKeyFor(queryKey));\n }\n\n await this.writerActivateQuery(queryDefId, queryKey);\n }\n\n private async writerSaveEntity(entityKey: number, value: unknown, refIds?: number[]): Promise<void> {\n await this.setValue(entityKey, value, refIds ? new Set(refIds) : undefined);\n }\n\n private async writerActivateQuery(queryDefId: string, queryKey: number): Promise<void> {\n if (!(await this.delegate!.has(valueKeyFor(queryKey)))) {\n // Query not in store, nothing to do\n return;\n }\n\n let queue = this.queues.get(queryDefId);\n\n if (queue === undefined) {\n // For now, use default max count. In a real implementation,\n // we'd need to pass queryDef or maxCount through the message\n const maxCount = DEFAULT_MAX_COUNT;\n queue = await this.delegate!.getBuffer(queueKeyFor(queryDefId));\n\n if (queue === undefined) {\n queue = new Uint32Array(maxCount);\n await this.delegate!.setBuffer(queueKeyFor(queryDefId), queue);\n } else if (queue.length !== maxCount) {\n queue = new Uint32Array(queue.buffer, 0, maxCount);\n await this.delegate!.setBuffer(queueKeyFor(queryDefId), queue);\n }\n\n this.queues.set(queryDefId, queue);\n }\n\n const indexOfKey = queue.indexOf(queryKey);\n\n // Item already in queue, move to front\n if (indexOfKey >= 0) {\n if (indexOfKey === 0) {\n // Already at front, nothing to do\n return;\n }\n // Shift items right to make space at front\n queue.copyWithin(1, 0, indexOfKey);\n queue[0] = queryKey;\n return;\n }\n\n // Item not in queue, add to front and evict tail\n const evicted = queue[queue.length - 1];\n queue.copyWithin(1, 0, queue.length - 1);\n queue[0] = queryKey;\n\n if (evicted !== 0) {\n await this.writerDeleteValue(evicted);\n await this.delegate!.delete(updatedAtKeyFor(evicted));\n }\n }\n\n private async setValue(id: number, value: unknown, refIds?: Set<number>): Promise<void> {\n const delegate = this.delegate!;\n\n await delegate.setString(valueKeyFor(id), JSON.stringify(value));\n\n const refIdsKey = refIdsKeyFor(id);\n\n const prevRefIds = await delegate.getBuffer(refIdsKey);\n\n if (refIds === undefined || refIds.size === 0) {\n await delegate.delete(refIdsKey);\n\n // Decrement all previous refs\n if (prevRefIds !== undefined) {\n for (let i = 0; i < prevRefIds.length; i++) {\n const refId = prevRefIds[i];\n await this.decrementRefCount(refId);\n }\n }\n } else {\n // Convert the set to a Uint32Array and capture all the refIds before we\n // delete previous ones from the set\n const newRefIds = new Uint32Array(refIds);\n\n if (prevRefIds !== undefined) {\n // Process new refs: increment if not in old\n for (let i = 0; i < prevRefIds.length; i++) {\n const refId = prevRefIds[i];\n\n if (refIds.has(refId)) {\n refIds.delete(refId);\n } else {\n await this.decrementRefCount(refId);\n }\n }\n }\n\n // No previous refs, increment all unique new refs\n for (const refId of refIds) {\n await this.incrementRefCount(refId);\n }\n\n await delegate.setBuffer(refIdsKey, newRefIds);\n }\n }\n\n private async writerDeleteValue(id: number): Promise<void> {\n const delegate = this.delegate!;\n\n await delegate.delete(valueKeyFor(id));\n await delegate.delete(refCountKeyFor(id));\n\n const refIds = await delegate.getBuffer(refIdsKeyFor(id));\n await delegate.delete(refIdsKeyFor(id)); // Clean up the refIds key\n\n if (refIds === undefined) {\n return;\n }\n\n // Decrement ref counts for all referenced entities\n for (const refId of refIds) {\n if (refId !== 0) {\n await this.decrementRefCount(refId);\n }\n }\n }\n\n private async incrementRefCount(refId: number): Promise<void> {\n const delegate = this.delegate!;\n const refCountKey = refCountKeyFor(refId);\n const currentCount = (await delegate.getNumber(refCountKey)) ?? 0;\n const newCount = currentCount + 1;\n await delegate.setNumber(refCountKey, newCount);\n }\n\n private async decrementRefCount(refId: number): Promise<void> {\n const delegate = this.delegate!;\n const refCountKey = refCountKeyFor(refId);\n const currentCount = await delegate.getNumber(refCountKey);\n\n if (currentCount === undefined) {\n // Already deleted or never existed\n return;\n }\n\n const newCount = currentCount - 1;\n\n if (newCount === 0) {\n // Entity exists, cascade delete it\n await this.writerDeleteValue(refId);\n } else {\n await delegate.setNumber(refCountKey, newCount);\n }\n }\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,214 @@
1
+ import { u as updatedAtKeyFor, v as valueKeyFor, r as refIdsKeyFor, s as streamOrphanRefsKeyFor, o as optimisticInsertRefsKeyFor, b as refCountKeyFor } from "../shared-Br5plsKm.js";
2
+ const DEFAULT_MAX_COUNT = 50;
3
+ const DEFAULT_GC_TIME = 1e3 * 60 * 60 * 24;
4
+ class MemoryPersistentStore {
5
+ kv = /* @__PURE__ */ Object.create(null);
6
+ has(key) {
7
+ return key in this.kv;
8
+ }
9
+ getString(key) {
10
+ return this.kv[key];
11
+ }
12
+ setString(key, value) {
13
+ this.kv[key] = value;
14
+ }
15
+ getNumber(key) {
16
+ return this.kv[key];
17
+ }
18
+ setNumber(key, value) {
19
+ this.kv[key] = value;
20
+ }
21
+ getBuffer(key) {
22
+ return this.kv[key];
23
+ }
24
+ setBuffer(key, value) {
25
+ this.kv[key] = value;
26
+ }
27
+ delete(key) {
28
+ delete this.kv[key];
29
+ }
30
+ }
31
+ const queueKeyFor = (queryDefId) => `sq:doc:queue:${queryDefId}`;
32
+ class SyncQueryStore {
33
+ constructor(kv) {
34
+ this.kv = kv;
35
+ }
36
+ queues = /* @__PURE__ */ new Map();
37
+ loadQuery(queryDef, queryKey, entityMap) {
38
+ const updatedAt = this.kv.getNumber(updatedAtKeyFor(queryKey));
39
+ if (updatedAt === void 0 || updatedAt < Date.now() - (queryDef.cache?.gcTime ?? DEFAULT_GC_TIME)) {
40
+ return;
41
+ }
42
+ const valueStr = this.kv.getString(valueKeyFor(queryKey));
43
+ if (valueStr === void 0) {
44
+ return;
45
+ }
46
+ const entityIds = this.kv.getBuffer(refIdsKeyFor(queryKey));
47
+ if (entityIds !== void 0) {
48
+ this.preloadEntities(entityIds, entityMap);
49
+ }
50
+ const streamOrphanRefs = this.kv.getBuffer(streamOrphanRefsKeyFor(queryKey));
51
+ const optimisticInsertRefs = this.kv.getBuffer(optimisticInsertRefsKeyFor(queryKey));
52
+ if (streamOrphanRefs !== void 0) {
53
+ this.preloadEntities(streamOrphanRefs, entityMap);
54
+ }
55
+ if (optimisticInsertRefs !== void 0) {
56
+ this.preloadEntities(optimisticInsertRefs, entityMap);
57
+ }
58
+ let extra;
59
+ if (streamOrphanRefs !== void 0 || optimisticInsertRefs !== void 0) {
60
+ extra = {};
61
+ if (streamOrphanRefs !== void 0) {
62
+ extra.streamOrphanRefs = Array.from(streamOrphanRefs);
63
+ }
64
+ if (optimisticInsertRefs !== void 0) {
65
+ extra.optimisticInsertRefs = Array.from(optimisticInsertRefs);
66
+ }
67
+ }
68
+ this.activateQuery(queryDef, queryKey);
69
+ return {
70
+ value: JSON.parse(valueStr),
71
+ refIds: entityIds === void 0 ? void 0 : new Set(entityIds ?? []),
72
+ updatedAt,
73
+ extra
74
+ };
75
+ }
76
+ preloadEntities(entityIds, entityMap) {
77
+ for (const entityId of entityIds) {
78
+ const entityValue = this.kv.getString(valueKeyFor(entityId));
79
+ if (entityValue === void 0) {
80
+ continue;
81
+ }
82
+ const entity = JSON.parse(entityValue);
83
+ entityMap.setPreloadedEntity(entityId, entity);
84
+ const childIds = this.kv.getBuffer(refIdsKeyFor(entityId));
85
+ if (childIds === void 0) {
86
+ continue;
87
+ }
88
+ this.preloadEntities(childIds, entityMap);
89
+ }
90
+ }
91
+ saveQuery(queryDef, queryKey, value, updatedAt, refIds, extra) {
92
+ this.setValue(queryKey, value, refIds);
93
+ this.kv.setNumber(updatedAtKeyFor(queryKey), updatedAt);
94
+ if (extra?.streamOrphanRefs !== void 0 && extra.streamOrphanRefs.length > 0) {
95
+ this.kv.setBuffer(streamOrphanRefsKeyFor(queryKey), new Uint32Array(extra.streamOrphanRefs));
96
+ } else {
97
+ this.kv.delete(streamOrphanRefsKeyFor(queryKey));
98
+ }
99
+ if (extra?.optimisticInsertRefs !== void 0 && extra.optimisticInsertRefs.length > 0) {
100
+ this.kv.setBuffer(optimisticInsertRefsKeyFor(queryKey), new Uint32Array(extra.optimisticInsertRefs));
101
+ } else {
102
+ this.kv.delete(optimisticInsertRefsKeyFor(queryKey));
103
+ }
104
+ this.activateQuery(queryDef, queryKey);
105
+ }
106
+ saveEntity(entityKey, value, refIds) {
107
+ this.setValue(entityKey, value, refIds);
108
+ }
109
+ activateQuery(queryDef, queryKey) {
110
+ if (!this.kv.has(valueKeyFor(queryKey))) {
111
+ return;
112
+ }
113
+ let queue = this.queues.get(queryDef.id);
114
+ if (queue === void 0) {
115
+ const maxCount = queryDef.cache?.maxCount ?? DEFAULT_MAX_COUNT;
116
+ queue = this.kv.getBuffer(queueKeyFor(queryDef.id));
117
+ if (queue === void 0) {
118
+ queue = new Uint32Array(maxCount);
119
+ this.kv.setBuffer(queueKeyFor(queryDef.id), queue);
120
+ } else if (queue.length !== maxCount) {
121
+ queue = new Uint32Array(queue.buffer, 0, maxCount);
122
+ this.kv.setBuffer(queueKeyFor(queryDef.id), queue);
123
+ }
124
+ this.queues.set(queryDef.id, queue);
125
+ }
126
+ const indexOfKey = queue.indexOf(queryKey);
127
+ if (indexOfKey >= 0) {
128
+ if (indexOfKey === 0) {
129
+ return;
130
+ }
131
+ queue.copyWithin(1, 0, indexOfKey);
132
+ queue[0] = queryKey;
133
+ return;
134
+ }
135
+ const evicted = queue[queue.length - 1];
136
+ queue.copyWithin(1, 0, queue.length - 1);
137
+ queue[0] = queryKey;
138
+ if (evicted !== 0) {
139
+ this.deleteQuery(evicted);
140
+ this.kv.delete(updatedAtKeyFor(evicted));
141
+ }
142
+ }
143
+ setValue(id, value, refIds) {
144
+ const kv = this.kv;
145
+ kv.setString(valueKeyFor(id), JSON.stringify(value));
146
+ const refIdsKey = refIdsKeyFor(id);
147
+ const prevRefIds = kv.getBuffer(refIdsKey);
148
+ if (refIds === void 0 || refIds.size === 0) {
149
+ kv.delete(refIdsKey);
150
+ if (prevRefIds !== void 0) {
151
+ for (let i = 0; i < prevRefIds.length; i++) {
152
+ const refId = prevRefIds[i];
153
+ this.decrementRefCount(refId);
154
+ }
155
+ }
156
+ } else {
157
+ const newRefIds = new Uint32Array(refIds);
158
+ if (prevRefIds !== void 0) {
159
+ for (let i = 0; i < prevRefIds.length; i++) {
160
+ const refId = prevRefIds[i];
161
+ if (refIds.has(refId)) {
162
+ refIds.delete(refId);
163
+ } else {
164
+ this.decrementRefCount(refId);
165
+ }
166
+ }
167
+ }
168
+ for (const refId of refIds) {
169
+ this.incrementRefCount(refId);
170
+ }
171
+ kv.setBuffer(refIdsKey, newRefIds);
172
+ }
173
+ }
174
+ deleteQuery(id) {
175
+ const kv = this.kv;
176
+ kv.delete(valueKeyFor(id));
177
+ kv.delete(refCountKeyFor(id));
178
+ const refIds = kv.getBuffer(refIdsKeyFor(id));
179
+ kv.delete(refIdsKeyFor(id));
180
+ if (refIds === void 0) {
181
+ return;
182
+ }
183
+ for (const refId of refIds) {
184
+ if (refId !== 0) {
185
+ this.decrementRefCount(refId);
186
+ }
187
+ }
188
+ }
189
+ incrementRefCount(refId) {
190
+ const refCountKey = refCountKeyFor(refId);
191
+ const currentCount = this.kv.getNumber(refCountKey) ?? 0;
192
+ const newCount = currentCount + 1;
193
+ this.kv.setNumber(refCountKey, newCount);
194
+ }
195
+ decrementRefCount(refId) {
196
+ const refCountKey = refCountKeyFor(refId);
197
+ const currentCount = this.kv.getNumber(refCountKey);
198
+ if (currentCount === void 0) {
199
+ return;
200
+ }
201
+ const newCount = currentCount - 1;
202
+ if (newCount === 0) {
203
+ this.deleteQuery(refId);
204
+ } else {
205
+ this.kv.setNumber(refCountKey, newCount);
206
+ }
207
+ }
208
+ }
209
+ export {
210
+ MemoryPersistentStore,
211
+ SyncQueryStore,
212
+ queueKeyFor
213
+ };
214
+ //# sourceMappingURL=sync.js.map