@supalive/core 0.1.3 → 0.1.5

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 (212) hide show
  1. package/README.md +308 -1
  2. package/dist/helper-CiacMqje.d.ts +14 -0
  3. package/dist/helper-CiacMqje.d.ts.map +1 -0
  4. package/dist/helper-zdJT5FUc.js +58 -0
  5. package/dist/helper-zdJT5FUc.js.map +1 -0
  6. package/dist/index-CTyXKcq_.d.ts +1736 -0
  7. package/dist/index-CTyXKcq_.d.ts.map +1 -0
  8. package/dist/mysql-C8SN443m.d.ts +104 -0
  9. package/dist/mysql-C8SN443m.d.ts.map +1 -0
  10. package/dist/mysql-DELSRrpY.js +569 -0
  11. package/dist/mysql-DELSRrpY.js.map +1 -0
  12. package/dist/overlap-checker-CVkbbuEQ.js +187 -0
  13. package/dist/overlap-checker-CVkbbuEQ.js.map +1 -0
  14. package/dist/postgres-DE-XyNAQ.js +823 -0
  15. package/dist/postgres-DE-XyNAQ.js.map +1 -0
  16. package/dist/postgres-D_gwCHx-.d.ts +108 -0
  17. package/dist/postgres-D_gwCHx-.d.ts.map +1 -0
  18. package/dist/query-CbQLjeME.js +713 -0
  19. package/dist/query-CbQLjeME.js.map +1 -0
  20. package/dist/realtime_db-D9p2X2PH.js +246 -0
  21. package/dist/realtime_db-D9p2X2PH.js.map +1 -0
  22. package/dist/router-DlTYWpop.js +81 -0
  23. package/dist/router-DlTYWpop.js.map +1 -0
  24. package/dist/schema-SKcIWHfo.js +167 -0
  25. package/dist/schema-SKcIWHfo.js.map +1 -0
  26. package/dist/src/client/index.d.ts +2 -17
  27. package/dist/src/client/index.js +1151 -18
  28. package/dist/src/client/index.js.map +1 -1
  29. package/dist/src/exports/mysql.d.ts +2 -2
  30. package/dist/src/exports/mysql.js +2 -2
  31. package/dist/src/exports/postgres.d.ts +2 -2
  32. package/dist/src/exports/postgres.js +2 -2
  33. package/dist/src/exports/procedure.d.ts +3 -5
  34. package/dist/src/exports/procedure.js +5 -5
  35. package/dist/src/exports/server.d.ts +368 -2
  36. package/dist/src/exports/server.d.ts.map +1 -1
  37. package/dist/src/exports/server.js +1346 -2
  38. package/dist/src/exports/server.js.map +1 -1
  39. package/dist/src/exports/subscription-manager-worker-entry.d.ts +1 -0
  40. package/dist/src/exports/subscription-manager-worker-entry.js +115 -0
  41. package/dist/src/exports/subscription-manager-worker-entry.js.map +1 -0
  42. package/dist/src/exports/types.d.ts +4 -6
  43. package/dist/src/exports/types.js +5 -6
  44. package/dist/subscription-worker-BurdPO8d.js +511 -0
  45. package/dist/subscription-worker-BurdPO8d.js.map +1 -0
  46. package/dist/types_client_rpc-CIsjQQGG.js +105 -0
  47. package/dist/types_client_rpc-CIsjQQGG.js.map +1 -0
  48. package/dist/types_db-Ctf-ksoy.js +168 -0
  49. package/dist/types_db-Ctf-ksoy.js.map +1 -0
  50. package/dist/types_server-Ch56y8L3.d.ts +216 -0
  51. package/dist/types_server-Ch56y8L3.d.ts.map +1 -0
  52. package/dist/types_server-Dk6o_B7N.js +24 -0
  53. package/dist/types_server-Dk6o_B7N.js.map +1 -0
  54. package/package.json +3 -3
  55. package/dist/src/client/caller_client.d.ts +0 -42
  56. package/dist/src/client/caller_client.d.ts.map +0 -1
  57. package/dist/src/client/caller_client.js +0 -77
  58. package/dist/src/client/caller_client.js.map +0 -1
  59. package/dist/src/client/client.d.ts +0 -149
  60. package/dist/src/client/client.d.ts.map +0 -1
  61. package/dist/src/client/client.js +0 -308
  62. package/dist/src/client/client.js.map +0 -1
  63. package/dist/src/client/index.d.ts.map +0 -1
  64. package/dist/src/client/sub_key.d.ts +0 -20
  65. package/dist/src/client/sub_key.d.ts.map +0 -1
  66. package/dist/src/client/sub_key.js +0 -37
  67. package/dist/src/client/sub_key.js.map +0 -1
  68. package/dist/src/client/ws_client_manager.d.ts +0 -268
  69. package/dist/src/client/ws_client_manager.d.ts.map +0 -1
  70. package/dist/src/client/ws_client_manager.js +0 -1013
  71. package/dist/src/client/ws_client_manager.js.map +0 -1
  72. package/dist/src/config.d.ts +0 -117
  73. package/dist/src/config.d.ts.map +0 -1
  74. package/dist/src/config.js +0 -2
  75. package/dist/src/config.js.map +0 -1
  76. package/dist/src/db/bytes.d.ts +0 -4
  77. package/dist/src/db/bytes.d.ts.map +0 -1
  78. package/dist/src/db/bytes.js +0 -24
  79. package/dist/src/db/bytes.js.map +0 -1
  80. package/dist/src/db/cache.d.ts +0 -30
  81. package/dist/src/db/cache.d.ts.map +0 -1
  82. package/dist/src/db/cache.js +0 -153
  83. package/dist/src/db/cache.js.map +0 -1
  84. package/dist/src/db/codec.d.ts +0 -10
  85. package/dist/src/db/codec.d.ts.map +0 -1
  86. package/dist/src/db/codec.js +0 -73
  87. package/dist/src/db/codec.js.map +0 -1
  88. package/dist/src/db/context.d.ts +0 -28
  89. package/dist/src/db/context.d.ts.map +0 -1
  90. package/dist/src/db/context.js +0 -147
  91. package/dist/src/db/context.js.map +0 -1
  92. package/dist/src/db/db.d.ts +0 -154
  93. package/dist/src/db/db.d.ts.map +0 -1
  94. package/dist/src/db/db.js +0 -23
  95. package/dist/src/db/db.js.map +0 -1
  96. package/dist/src/db/mysql.d.ts +0 -120
  97. package/dist/src/db/mysql.d.ts.map +0 -1
  98. package/dist/src/db/mysql.js +0 -708
  99. package/dist/src/db/mysql.js.map +0 -1
  100. package/dist/src/db/postgres.d.ts +0 -116
  101. package/dist/src/db/postgres.d.ts.map +0 -1
  102. package/dist/src/db/postgres.js +0 -998
  103. package/dist/src/db/postgres.js.map +0 -1
  104. package/dist/src/db/query.d.ts +0 -174
  105. package/dist/src/db/query.d.ts.map +0 -1
  106. package/dist/src/db/query.js +0 -790
  107. package/dist/src/db/query.js.map +0 -1
  108. package/dist/src/db/query_definition.d.ts +0 -54
  109. package/dist/src/db/query_definition.d.ts.map +0 -1
  110. package/dist/src/db/query_definition.js +0 -47
  111. package/dist/src/db/query_definition.js.map +0 -1
  112. package/dist/src/db/realtime_db.d.ts +0 -19
  113. package/dist/src/db/realtime_db.d.ts.map +0 -1
  114. package/dist/src/db/realtime_db.js +0 -98
  115. package/dist/src/db/realtime_db.js.map +0 -1
  116. package/dist/src/db/schema.d.ts +0 -110
  117. package/dist/src/db/schema.d.ts.map +0 -1
  118. package/dist/src/db/schema.js +0 -47
  119. package/dist/src/db/schema.js.map +0 -1
  120. package/dist/src/db/types_client_rpc.d.ts +0 -157
  121. package/dist/src/db/types_client_rpc.d.ts.map +0 -1
  122. package/dist/src/db/types_client_rpc.js +0 -106
  123. package/dist/src/db/types_client_rpc.js.map +0 -1
  124. package/dist/src/db/types_db.d.ts +0 -236
  125. package/dist/src/db/types_db.d.ts.map +0 -1
  126. package/dist/src/db/types_db.js +0 -188
  127. package/dist/src/db/types_db.js.map +0 -1
  128. package/dist/src/exports/mysql.d.ts.map +0 -1
  129. package/dist/src/exports/mysql.js.map +0 -1
  130. package/dist/src/exports/postgres.d.ts.map +0 -1
  131. package/dist/src/exports/postgres.js.map +0 -1
  132. package/dist/src/exports/procedure.d.ts.map +0 -1
  133. package/dist/src/exports/procedure.js.map +0 -1
  134. package/dist/src/exports/types.d.ts.map +0 -1
  135. package/dist/src/exports/types.js.map +0 -1
  136. package/dist/src/helper.d.ts +0 -11
  137. package/dist/src/helper.d.ts.map +0 -1
  138. package/dist/src/helper.js +0 -45
  139. package/dist/src/helper.js.map +0 -1
  140. package/dist/src/logger.d.ts +0 -7
  141. package/dist/src/logger.d.ts.map +0 -1
  142. package/dist/src/logger.js +0 -45
  143. package/dist/src/logger.js.map +0 -1
  144. package/dist/src/router/index.d.ts +0 -4
  145. package/dist/src/router/index.d.ts.map +0 -1
  146. package/dist/src/router/index.js +0 -4
  147. package/dist/src/router/index.js.map +0 -1
  148. package/dist/src/router/procedure.d.ts +0 -204
  149. package/dist/src/router/procedure.d.ts.map +0 -1
  150. package/dist/src/router/procedure.js +0 -122
  151. package/dist/src/router/procedure.js.map +0 -1
  152. package/dist/src/router/router.d.ts +0 -88
  153. package/dist/src/router/router.d.ts.map +0 -1
  154. package/dist/src/router/router.js +0 -88
  155. package/dist/src/router/router.js.map +0 -1
  156. package/dist/src/server/hash.d.ts +0 -12
  157. package/dist/src/server/hash.d.ts.map +0 -1
  158. package/dist/src/server/hash.js +0 -20
  159. package/dist/src/server/hash.js.map +0 -1
  160. package/dist/src/server/hash.test.d.ts +0 -2
  161. package/dist/src/server/hash.test.d.ts.map +0 -1
  162. package/dist/src/server/hash.test.js +0 -43
  163. package/dist/src/server/hash.test.js.map +0 -1
  164. package/dist/src/server/index.d.ts +0 -8
  165. package/dist/src/server/index.d.ts.map +0 -1
  166. package/dist/src/server/index.js +0 -7
  167. package/dist/src/server/index.js.map +0 -1
  168. package/dist/src/server/overlap-checker.d.ts +0 -18
  169. package/dist/src/server/overlap-checker.d.ts.map +0 -1
  170. package/dist/src/server/overlap-checker.js +0 -247
  171. package/dist/src/server/overlap-checker.js.map +0 -1
  172. package/dist/src/server/sub_hash.d.ts +0 -23
  173. package/dist/src/server/sub_hash.d.ts.map +0 -1
  174. package/dist/src/server/sub_hash.js +0 -38
  175. package/dist/src/server/sub_hash.js.map +0 -1
  176. package/dist/src/server/subscription-manager-client.d.ts +0 -120
  177. package/dist/src/server/subscription-manager-client.d.ts.map +0 -1
  178. package/dist/src/server/subscription-manager-client.js +0 -207
  179. package/dist/src/server/subscription-manager-client.js.map +0 -1
  180. package/dist/src/server/subscription-manager-types.d.ts +0 -168
  181. package/dist/src/server/subscription-manager-types.d.ts.map +0 -1
  182. package/dist/src/server/subscription-manager-types.js +0 -94
  183. package/dist/src/server/subscription-manager-types.js.map +0 -1
  184. package/dist/src/server/subscription-manager-worker-entry.d.ts +0 -2
  185. package/dist/src/server/subscription-manager-worker-entry.d.ts.map +0 -1
  186. package/dist/src/server/subscription-manager-worker-entry.js +0 -127
  187. package/dist/src/server/subscription-manager-worker-entry.js.map +0 -1
  188. package/dist/src/server/subscription-manager-worker-protocol.d.ts +0 -40
  189. package/dist/src/server/subscription-manager-worker-protocol.d.ts.map +0 -1
  190. package/dist/src/server/subscription-manager-worker-protocol.js +0 -20
  191. package/dist/src/server/subscription-manager-worker-protocol.js.map +0 -1
  192. package/dist/src/server/subscription-manager.d.ts +0 -32
  193. package/dist/src/server/subscription-manager.d.ts.map +0 -1
  194. package/dist/src/server/subscription-manager.js +0 -249
  195. package/dist/src/server/subscription-manager.js.map +0 -1
  196. package/dist/src/server/subscription-manager.test.d.ts +0 -2
  197. package/dist/src/server/subscription-manager.test.d.ts.map +0 -1
  198. package/dist/src/server/subscription-manager.test.js +0 -610
  199. package/dist/src/server/subscription-manager.test.js.map +0 -1
  200. package/dist/src/server/subscription-worker.d.ts +0 -32
  201. package/dist/src/server/subscription-worker.d.ts.map +0 -1
  202. package/dist/src/server/subscription-worker.js +0 -190
  203. package/dist/src/server/subscription-worker.js.map +0 -1
  204. package/dist/src/server/supalive-server.d.ts +0 -158
  205. package/dist/src/server/supalive-server.d.ts.map +0 -1
  206. package/dist/src/server/supalive-server.js +0 -1048
  207. package/dist/src/server/supalive-server.js.map +0 -1
  208. package/dist/src/server/types_server.d.ts +0 -96
  209. package/dist/src/server/types_server.d.ts.map +0 -1
  210. package/dist/src/server/types_server.js +0 -36
  211. package/dist/src/server/types_server.js.map +0 -1
  212. package/dist/tsconfig.tsbuildinfo +0 -1
@@ -0,0 +1,187 @@
1
+ import { a as jsonPathExtract, i as jsonPathExists, r as jsonContains } from "./query-CbQLjeME.js";
2
+ import { a as utf8Decode, i as bytesEqual } from "./helper-zdJT5FUc.js";
3
+ import { C as normalizeIdToBytes } from "./types_db-Ctf-ksoy.js";
4
+ //#region src/server/overlap-checker.ts
5
+ function mapReadEntryToRaw(entry) {
6
+ if (entry.kind === "point") return {
7
+ kind: "point",
8
+ tableId: entry.tableId,
9
+ id: normalizeIdToBytes(entry.id),
10
+ table: entry.table
11
+ };
12
+ else return {
13
+ kind: "range",
14
+ tableId: entry.tableId,
15
+ table: entry.table,
16
+ predicate: entry.predicate,
17
+ columns: entry.columns,
18
+ offset: entry.offset,
19
+ orderBy: entry.orderBy,
20
+ limit: entry.limit
21
+ };
22
+ }
23
+ function mapReadSetToRaw(readSet) {
24
+ return readSet.map(mapReadEntryToRaw);
25
+ }
26
+ function mapWriteEntryToRaw(entry) {
27
+ return {
28
+ table: entry.table,
29
+ tableId: entry.tableId,
30
+ id: normalizeIdToBytes(entry.id),
31
+ op: entry.op,
32
+ data: entry.data,
33
+ prevData: entry.prevData
34
+ };
35
+ }
36
+ function mapWriteSetToRaw(writeSet) {
37
+ return writeSet.map(mapWriteEntryToRaw);
38
+ }
39
+ function evaluatePredicateAgainstRow(rowData, predicate) {
40
+ switch (predicate.kind) {
41
+ case "and": {
42
+ let hasUnknown = false;
43
+ for (const child of predicate.children) {
44
+ const r = evaluatePredicateAgainstRow(rowData, child);
45
+ if (r === "no") return "no";
46
+ if (r === "unknown") hasUnknown = true;
47
+ }
48
+ return hasUnknown ? "unknown" : "yes";
49
+ }
50
+ case "or": {
51
+ let hasUnknown = false;
52
+ for (const child of predicate.children) {
53
+ const r = evaluatePredicateAgainstRow(rowData, child);
54
+ if (r === "yes") return "yes";
55
+ if (r === "unknown") hasUnknown = true;
56
+ }
57
+ return hasUnknown ? "unknown" : "no";
58
+ }
59
+ case "leaf": {
60
+ if (!(predicate.column in rowData)) return "unknown";
61
+ const val = rowData[predicate.column];
62
+ switch (predicate.operator) {
63
+ case "=": return val === predicate.value ? "yes" : "no";
64
+ case "!=": return val !== predicate.value ? "yes" : "no";
65
+ case ">": return val > predicate.value ? "yes" : "no";
66
+ case ">=": return val >= predicate.value ? "yes" : "no";
67
+ case "<": return val < predicate.value ? "yes" : "no";
68
+ case "<=": return val <= predicate.value ? "yes" : "no";
69
+ case "between": return val >= predicate.value && val <= predicate.value2 ? "yes" : "no";
70
+ case "like":
71
+ case "contains":
72
+ case "ilike":
73
+ case "icontains": {
74
+ if (typeof val !== "string" || typeof predicate.value !== "string") return "no";
75
+ const haystack = predicate.operator === "ilike" || predicate.operator === "icontains" ? val.toLowerCase() : val;
76
+ const needle = predicate.operator === "ilike" || predicate.operator === "icontains" ? predicate.value.toLowerCase() : predicate.value;
77
+ const pattern = predicate.operator === "contains" || predicate.operator === "icontains" ? `%${needle}%` : needle;
78
+ return new RegExp("^" + pattern.replace(/%/g, ".*").replace(/_/g, ".") + "$").test(haystack) ? "yes" : "no";
79
+ }
80
+ case "jsonContains": {
81
+ const candidate = decodeJsonLeafValue(predicate);
82
+ const target = predicate.path !== void 0 ? jsonPathExtract(val, predicate.path) : val;
83
+ if (target === void 0) return "no";
84
+ return jsonContains(target, candidate) ? "yes" : "no";
85
+ }
86
+ case "jsonContainedBy": {
87
+ const candidate = decodeJsonLeafValue(predicate);
88
+ const target = predicate.path !== void 0 ? jsonPathExtract(val, predicate.path) : val;
89
+ if (target === void 0) return "no";
90
+ return jsonContains(candidate, target) ? "yes" : "no";
91
+ }
92
+ case "jsonHasKey": {
93
+ if (predicate.mode && Array.isArray(predicate.value)) {
94
+ const paths = predicate.value;
95
+ if (paths.length === 0) return "no";
96
+ return (predicate.mode === "all" ? paths.every((p) => jsonPathExists(val, p)) : paths.some((p) => jsonPathExists(val, p))) ? "yes" : "no";
97
+ }
98
+ if (predicate.raw) return jsonPathExists(val, predicate.value) ? "yes" : "no";
99
+ const key = predicate.value;
100
+ if (val === null || typeof val !== "object") return "no";
101
+ if (Array.isArray(val)) return val.includes(key) ? "yes" : "no";
102
+ return key in val ? "yes" : "no";
103
+ }
104
+ case "jsonArrayContains": {
105
+ const candidate = decodeJsonLeafValue(predicate);
106
+ const target = predicate.path !== void 0 ? jsonPathExtract(val, predicate.path) : val;
107
+ if (!Array.isArray(target)) return "no";
108
+ return target.some((el) => jsonContains(el, candidate)) ? "yes" : "no";
109
+ }
110
+ case "isNull": return val === null ? "yes" : "no";
111
+ case "isNotNull": return val !== null ? "yes" : "no";
112
+ default: return "unknown";
113
+ }
114
+ }
115
+ }
116
+ }
117
+ function decodeJsonLeafValue(leaf) {
118
+ if (!leaf.raw) return leaf.value;
119
+ if (typeof leaf.value !== "string") return leaf.value;
120
+ try {
121
+ return JSON.parse(leaf.value);
122
+ } catch {
123
+ return leaf.value;
124
+ }
125
+ }
126
+ function parseLogData(log) {
127
+ if (log._parsedData !== void 0) return log._parsedData;
128
+ const data = log.data.length > 0 ? JSON.parse(utf8Decode(log.data)) : null;
129
+ log._parsedData = data;
130
+ return data;
131
+ }
132
+ function checkLogsAffectReadSet(logs, rawReadSet) {
133
+ for (const log of logs) for (const rawRead of rawReadSet) {
134
+ if (!bytesEqual(log.tableId, rawRead.tableId)) continue;
135
+ if (rawRead.kind === "point" ? checkPointReadOverlap(log, rawRead) : checkRangeReadOverlap(log, rawRead)) return true;
136
+ }
137
+ return false;
138
+ }
139
+ function checkPointReadOverlap(log, rawRead) {
140
+ return bytesEqual(log.id, rawRead.id);
141
+ }
142
+ function checkRangeReadOverlap(log, rawRead) {
143
+ const logData = parseLogData(log);
144
+ if (!logData) return true;
145
+ const op = logData.op ?? "update";
146
+ const data = logData.data;
147
+ const prevData = logData.prevData;
148
+ return checkRowWriteAffectsRange(op, prevData, data, rawRead.predicate);
149
+ }
150
+ function checkWriteSetAffectsReadSet(writeSet, rawReadSet) {
151
+ for (const write of writeSet) for (const rawRead of rawReadSet) {
152
+ if (!bytesEqual(write.tableId, rawRead.tableId)) continue;
153
+ if (checkWriteAffectsRawReadEntry(write, rawRead)) return true;
154
+ }
155
+ return false;
156
+ }
157
+ function checkWriteAffectsRawReadEntry(write, rawRead) {
158
+ if (rawRead.kind === "point") return bytesEqual(write.id, rawRead.id);
159
+ return checkRowWriteAffectsRange(write.op, write.prevData, write.data, rawRead.predicate);
160
+ }
161
+ /**
162
+ * Evaluate whether a write affects a range subscription, given the row's
163
+ * prior and post state. The write is considered affecting if EITHER side
164
+ * matched the predicate — that catches:
165
+ * - rows entering the result set (prev "no", post "yes")
166
+ * - rows leaving the result set (prev "yes", post "no")
167
+ * - rows changing while still in the set (prev "yes", post "yes")
168
+ * Skipped only if both sides are a definite "no".
169
+ *
170
+ * When prevData is missing (e.g. inserts, or commit logs predating this
171
+ * change), we fall back to conservative "unknown" on that side.
172
+ */
173
+ function checkRowWriteAffectsRange(op, prevData, data, predicate) {
174
+ const prevVerdict = prevData ? evaluatePredicateAgainstRow(prevData, predicate) : op === "insert" ? "no" : "unknown";
175
+ let postVerdict;
176
+ if (op === "delete") postVerdict = "no";
177
+ else if (data) postVerdict = evaluatePredicateAgainstRow(prevData ? {
178
+ ...prevData,
179
+ ...data
180
+ } : data, predicate);
181
+ else postVerdict = "unknown";
182
+ return prevVerdict !== "no" || postVerdict !== "no";
183
+ }
184
+ //#endregion
185
+ export { mapWriteSetToRaw as i, checkWriteSetAffectsReadSet as n, mapReadSetToRaw as r, checkLogsAffectReadSet as t };
186
+
187
+ //# sourceMappingURL=overlap-checker-CVkbbuEQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overlap-checker-CVkbbuEQ.js","names":[],"sources":["../src/server/overlap-checker.ts"],"sourcesContent":["import type {\n ReadEntry, CommitLogEntry,\n Predicate, WriteEntry, WriteOp,\n RawReadEntry, RawPointRead, RawRangeRead, LeafPredicate,\n} from \"../db/types_db\";\nimport { normalizeIdToBytes } from \"../db/types_db\";\nimport { bytesEqual, utf8Decode } from \"../db/bytes\";\nimport { jsonContains, jsonPathExists, jsonPathExtract } from \"../db/query\";\n\nexport interface RawWriteEntry {\n table: string;\n tableId: Uint8Array;\n id: Uint8Array;\n op: WriteOp;\n data?: Record<string, unknown>;\n prevData?: Record<string, unknown>;\n}\n\nexport function mapReadEntryToRaw(entry: ReadEntry): RawReadEntry {\n if (entry.kind === \"point\") {\n return {\n kind: \"point\",\n tableId: entry.tableId,\n id: normalizeIdToBytes(entry.id),\n table: entry.table,\n };\n } else {\n return {\n kind: \"range\",\n tableId: entry.tableId,\n table: entry.table,\n predicate: entry.predicate,\n columns: entry.columns,\n offset: entry.offset,\n orderBy: entry.orderBy,\n limit: entry.limit,\n };\n }\n}\n\nexport function mapReadSetToRaw(readSet: ReadEntry[]): RawReadEntry[] {\n return readSet.map(mapReadEntryToRaw);\n}\n\nexport function mapWriteEntryToRaw(entry: WriteEntry): RawWriteEntry {\n return {\n table: entry.table,\n tableId: entry.tableId,\n id: normalizeIdToBytes(entry.id),\n op: entry.op,\n data: entry.data,\n prevData: entry.prevData,\n };\n}\n\nexport function mapWriteSetToRaw(writeSet: WriteEntry[]): RawWriteEntry[] {\n return writeSet.map(mapWriteEntryToRaw);\n}\n\nexport type OverlapVerdict = \"yes\" | \"no\" | \"unknown\";\n\nexport function evaluatePredicateAgainstRow(\n rowData: Record<string, unknown>,\n predicate: Predicate\n): OverlapVerdict {\n switch (predicate.kind) {\n case \"and\": {\n let hasUnknown = false;\n for (const child of predicate.children) {\n const r = evaluatePredicateAgainstRow(rowData, child);\n if (r === \"no\") return \"no\";\n if (r === \"unknown\") hasUnknown = true;\n }\n return hasUnknown ? \"unknown\" : \"yes\";\n }\n case \"or\": {\n let hasUnknown = false;\n for (const child of predicate.children) {\n const r = evaluatePredicateAgainstRow(rowData, child);\n if (r === \"yes\") return \"yes\";\n if (r === \"unknown\") hasUnknown = true;\n }\n return hasUnknown ? \"unknown\" : \"no\";\n }\n case \"leaf\": {\n if (!(predicate.column in rowData)) return \"unknown\";\n const val = rowData[predicate.column];\n switch (predicate.operator) {\n case \"=\": return val === predicate.value ? \"yes\" : \"no\";\n case \"!=\": return val !== predicate.value ? \"yes\" : \"no\";\n case \">\": return (val as number) > (predicate.value as number) ? \"yes\" : \"no\";\n case \">=\": return (val as number) >= (predicate.value as number) ? \"yes\" : \"no\";\n case \"<\": return (val as number) < (predicate.value as number) ? \"yes\" : \"no\";\n case \"<=\": return (val as number) <= (predicate.value as number) ? \"yes\" : \"no\";\n case \"between\":\n return (val as number) >= (predicate.value as number) &&\n (val as number) <= (predicate.value2 as number) ? \"yes\" : \"no\";\n case \"like\":\n case \"contains\":\n case \"ilike\":\n case \"icontains\": {\n if (typeof val !== \"string\" || typeof predicate.value !== \"string\") return \"no\";\n const haystack = (predicate.operator === \"ilike\" || predicate.operator === \"icontains\")\n ? val.toLowerCase() : val;\n const needle = (predicate.operator === \"ilike\" || predicate.operator === \"icontains\")\n ? (predicate.value as string).toLowerCase() : predicate.value as string;\n const pattern = (predicate.operator === \"contains\" || predicate.operator === \"icontains\")\n ? `%${needle}%` : needle;\n const regex = new RegExp(\"^\" + pattern.replace(/%/g, \".*\").replace(/_/g, \".\") + \"$\");\n return regex.test(haystack) ? \"yes\" : \"no\";\n }\n case \"jsonContains\": {\n const candidate = decodeJsonLeafValue(predicate);\n const target = predicate.path !== undefined ? jsonPathExtract(val, predicate.path) : val;\n if (target === undefined) return \"no\";\n return jsonContains(target, candidate) ? \"yes\" : \"no\";\n }\n case \"jsonContainedBy\": {\n const candidate = decodeJsonLeafValue(predicate);\n const target = predicate.path !== undefined ? jsonPathExtract(val, predicate.path) : val;\n if (target === undefined) return \"no\";\n return jsonContains(candidate, target) ? \"yes\" : \"no\";\n }\n case \"jsonHasKey\": {\n if (predicate.mode && Array.isArray(predicate.value)) {\n const paths = predicate.value as string[];\n if (paths.length === 0) return \"no\";\n const verdict = predicate.mode === \"all\"\n ? paths.every(p => jsonPathExists(val, p))\n : paths.some(p => jsonPathExists(val, p));\n return verdict ? \"yes\" : \"no\";\n }\n if (predicate.raw) {\n return jsonPathExists(val, predicate.value as string) ? \"yes\" : \"no\";\n }\n const key = predicate.value as string;\n if (val === null || typeof val !== \"object\") return \"no\";\n if (Array.isArray(val)) return (val as unknown[]).includes(key) ? \"yes\" : \"no\";\n return key in (val as object) ? \"yes\" : \"no\";\n }\n case \"jsonArrayContains\": {\n const candidate = decodeJsonLeafValue(predicate);\n const target = predicate.path !== undefined ? jsonPathExtract(val, predicate.path) : val;\n if (!Array.isArray(target)) return \"no\";\n return (target as unknown[]).some(el => jsonContains(el, candidate)) ? \"yes\" : \"no\";\n }\n case \"isNull\": return val === null ? \"yes\" : \"no\";\n case \"isNotNull\": return val !== null ? \"yes\" : \"no\";\n default: return \"unknown\";\n }\n }\n }\n}\n\nfunction decodeJsonLeafValue(leaf: LeafPredicate): unknown {\n if (!leaf.raw) return leaf.value;\n if (typeof leaf.value !== \"string\") return leaf.value;\n try { return JSON.parse(leaf.value); } catch { return leaf.value; }\n}\n\nfunction parseLogData(log: CommitLogEntry): Record<string, unknown> | null {\n if (log._parsedData !== undefined) {\n return log._parsedData;\n }\n const data = log.data.length > 0\n ? JSON.parse(utf8Decode(log.data)) as Record<string, unknown>\n : null;\n log._parsedData = data;\n return data;\n}\n\n\nexport function checkLogsAffectReadSet(\n logs: CommitLogEntry[],\n rawReadSet: RawReadEntry[]\n): boolean {\n for (const log of logs) {\n for (const rawRead of rawReadSet) {\n if (!bytesEqual(log.tableId, rawRead.tableId)) continue;\n\n const res = rawRead.kind === \"point\" ?\n checkPointReadOverlap(log, rawRead) :\n checkRangeReadOverlap(log, rawRead);\n\n if (res) {\n return true;\n }\n }\n }\n return false;\n}\n\nfunction checkPointReadOverlap(\n log: CommitLogEntry,\n rawRead: RawPointRead,\n): boolean {\n return bytesEqual(log.id, rawRead.id);\n}\n\nfunction checkRangeReadOverlap(\n log: CommitLogEntry,\n rawRead: RawRangeRead\n): boolean {\n const logData = parseLogData(log);\n\n // No envelope at all → can't reason, must conflict-out.\n if (!logData) { \n return true;\n }\n\n // Commit logs serialize the full WriteEntry (see PgDatabase.insertCommitLogs),\n // so extract the row state from it. Same prev-OR-post check as the\n // in-memory invalidator path.\n const op = (logData.op as WriteOp | undefined) ?? \"update\";\n const data = logData.data as Record<string, unknown> | undefined;\n const prevData = logData.prevData as Record<string, unknown> | undefined;\n\n return checkRowWriteAffectsRange(op, prevData, data, rawRead.predicate);\n}\n\nexport function checkWriteSetAffectsReadSet(\n writeSet: RawWriteEntry[],\n rawReadSet: RawReadEntry[]\n): boolean {\n for (const write of writeSet) {\n for (const rawRead of rawReadSet) {\n if (!bytesEqual(write.tableId, rawRead.tableId)) continue;\n\n if (checkWriteAffectsRawReadEntry(write, rawRead)) {\n return true;\n }\n }\n }\n return false;\n}\n\nfunction checkWriteAffectsRawReadEntry(\n write: RawWriteEntry,\n rawRead: RawReadEntry\n): boolean {\n if (rawRead.kind === \"point\") {\n return bytesEqual(write.id, rawRead.id);\n }\n return checkRowWriteAffectsRange(\n write.op,\n write.prevData,\n write.data,\n rawRead.predicate,\n );\n}\n\n/**\n * Evaluate whether a write affects a range subscription, given the row's\n * prior and post state. The write is considered affecting if EITHER side\n * matched the predicate — that catches:\n * - rows entering the result set (prev \"no\", post \"yes\")\n * - rows leaving the result set (prev \"yes\", post \"no\")\n * - rows changing while still in the set (prev \"yes\", post \"yes\")\n * Skipped only if both sides are a definite \"no\".\n *\n * When prevData is missing (e.g. inserts, or commit logs predating this\n * change), we fall back to conservative \"unknown\" on that side.\n */\nfunction checkRowWriteAffectsRange(\n op: WriteOp,\n prevData: Record<string, unknown> | undefined,\n data: Record<string, unknown> | undefined,\n predicate: RawRangeRead[\"predicate\"],\n): boolean {\n const prevVerdict: OverlapVerdict = prevData\n ? evaluatePredicateAgainstRow(prevData, predicate)\n : (op === \"insert\" ? \"no\" : \"unknown\");\n\n let postVerdict: OverlapVerdict;\n if (op === \"delete\") {\n postVerdict = \"no\";\n } else if (data) {\n // Merge over prevData so unchanged columns carry over — otherwise a\n // partial update (e.g. {title: \"x\"}) would be \"unknown\" on every\n // predicate column it doesn't touch.\n const post = prevData ? { ...prevData, ...data } : data;\n postVerdict = evaluatePredicateAgainstRow(post, predicate);\n } else {\n postVerdict = \"unknown\";\n }\n\n return prevVerdict !== \"no\" || postVerdict !== \"no\";\n}"],"mappings":"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"}