@reventlessdev/reventless-postgres 3.0.0-alpha.10 → 3.0.0-alpha.100

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 (117) hide show
  1. package/CHANGELOG.md +722 -0
  2. package/README.md +83 -0
  3. package/lib/bs/.compiler.log +2 -2
  4. package/lib/bs/ReventlessPostgres.cmt +0 -0
  5. package/lib/bs/ReventlessPostgres.mlmap +0 -2
  6. package/lib/bs/compiler-info.json +2 -2
  7. package/lib/bs/src/DcbEventLogStorage_Postgres-ReventlessPostgres.cmi +0 -0
  8. package/lib/bs/src/DcbEventLogStorage_Postgres-ReventlessPostgres.cmt +0 -0
  9. package/lib/bs/src/DcbEventLogStorage_Postgres.ast +0 -0
  10. package/lib/bs/src/DcbEventLogStorage_Postgres_Ops-ReventlessPostgres.cmi +0 -0
  11. package/lib/bs/src/DcbEventLogStorage_Postgres_Ops-ReventlessPostgres.cmt +0 -0
  12. package/lib/bs/src/DcbEventLogStorage_Postgres_Ops.ast +0 -0
  13. package/lib/bs/src/EventLogChangeFeed-ReventlessPostgres.cmi +0 -0
  14. package/lib/bs/src/EventLogChangeFeed-ReventlessPostgres.cmt +0 -0
  15. package/lib/bs/src/EventLogChangeFeed.ast +0 -0
  16. package/lib/bs/src/EventLogChangeFeed.res +5 -2
  17. package/lib/bs/src/EventLogChangeFeed.res.mjs +3 -3
  18. package/lib/bs/src/EventLogStorage_Postgres-ReventlessPostgres.cmi +0 -0
  19. package/lib/bs/src/EventLogStorage_Postgres-ReventlessPostgres.cmt +0 -0
  20. package/lib/bs/src/EventLogStorage_Postgres.ast +0 -0
  21. package/lib/bs/src/EventLogStorage_Postgres_Ops-ReventlessPostgres.cmi +0 -0
  22. package/lib/bs/src/EventLogStorage_Postgres_Ops-ReventlessPostgres.cmt +0 -0
  23. package/lib/bs/src/EventLogStorage_Postgres_Ops.ast +0 -0
  24. package/lib/bs/src/PgChangeFeed-ReventlessPostgres.cmi +0 -0
  25. package/lib/bs/src/PgChangeFeed-ReventlessPostgres.cmt +0 -0
  26. package/lib/bs/src/PgChangeFeed.ast +0 -0
  27. package/lib/bs/src/PgChangeFeed.res +6 -1
  28. package/lib/bs/src/PgChangeFeed.res.mjs +6 -6
  29. package/lib/bs/src/PgDriver-ReventlessPostgres.cmi +0 -0
  30. package/lib/bs/src/PgDriver-ReventlessPostgres.cmt +0 -0
  31. package/lib/bs/src/PgDriver-ReventlessPostgres.cmti +0 -0
  32. package/lib/bs/src/PgDriver.ast +0 -0
  33. package/lib/bs/src/PgDriver.iast +0 -0
  34. package/lib/bs/src/PgSchema-ReventlessPostgres.cmi +0 -0
  35. package/lib/bs/src/PgSchema-ReventlessPostgres.cmt +0 -0
  36. package/lib/bs/src/PgSchema.ast +0 -0
  37. package/lib/bs/src/QueryDbStorage_Postgres-ReventlessPostgres.cmi +0 -0
  38. package/lib/bs/src/QueryDbStorage_Postgres-ReventlessPostgres.cmt +0 -0
  39. package/lib/bs/src/QueryDbStorage_Postgres.ast +0 -0
  40. package/lib/bs/src/QueryDbStorage_Postgres.res +1 -1
  41. package/lib/bs/src/QueryDbStorage_Postgres.res.mjs +1 -1
  42. package/lib/bs/src/QueryDbStorage_Postgres_Ops-ReventlessPostgres.cmi +0 -0
  43. package/lib/bs/src/QueryDbStorage_Postgres_Ops-ReventlessPostgres.cmt +0 -0
  44. package/lib/bs/src/QueryDbStorage_Postgres_Ops.ast +0 -0
  45. package/lib/bs/src/QueryEnginePostgres-ReventlessPostgres.cmi +0 -0
  46. package/lib/bs/src/QueryEnginePostgres-ReventlessPostgres.cmt +0 -0
  47. package/lib/bs/src/QueryEnginePostgres.ast +0 -0
  48. package/lib/bs/src/QueryEnginePostgres.res +26 -12
  49. package/lib/bs/src/QueryEnginePostgres.res.mjs +26 -26
  50. package/lib/bs/tests/PostgresIntegrationTest-ReventlessPostgres.cmi +0 -0
  51. package/lib/bs/tests/PostgresIntegrationTest-ReventlessPostgres.cmt +0 -0
  52. package/lib/bs/tests/PostgresIntegrationTest.ast +0 -0
  53. package/lib/bs/tests/QueryEnginePostgresListPageTest-ReventlessPostgres.cmi +0 -0
  54. package/lib/bs/tests/QueryEnginePostgresListPageTest-ReventlessPostgres.cmt +0 -0
  55. package/lib/bs/tests/QueryEnginePostgresListPageTest.ast +0 -0
  56. package/lib/bs/tests/QueryEnginePostgresListPageTest.res.mjs +4 -4
  57. package/lib/ocaml/.compiler.log +2 -2
  58. package/lib/ocaml/DcbEventLogStorage_Postgres-ReventlessPostgres.cmi +0 -0
  59. package/lib/ocaml/DcbEventLogStorage_Postgres-ReventlessPostgres.cmt +0 -0
  60. package/lib/ocaml/DcbEventLogStorage_Postgres.ast +0 -0
  61. package/lib/ocaml/DcbEventLogStorage_Postgres_Ops-ReventlessPostgres.cmi +0 -0
  62. package/lib/ocaml/DcbEventLogStorage_Postgres_Ops-ReventlessPostgres.cmt +0 -0
  63. package/lib/ocaml/DcbEventLogStorage_Postgres_Ops.ast +0 -0
  64. package/lib/ocaml/EventLogChangeFeed-ReventlessPostgres.cmi +0 -0
  65. package/lib/ocaml/EventLogChangeFeed-ReventlessPostgres.cmt +0 -0
  66. package/lib/ocaml/EventLogChangeFeed.ast +0 -0
  67. package/lib/ocaml/EventLogChangeFeed.res +5 -2
  68. package/lib/ocaml/EventLogStorage_Postgres-ReventlessPostgres.cmi +0 -0
  69. package/lib/ocaml/EventLogStorage_Postgres-ReventlessPostgres.cmt +0 -0
  70. package/lib/ocaml/EventLogStorage_Postgres.ast +0 -0
  71. package/lib/ocaml/EventLogStorage_Postgres_Ops-ReventlessPostgres.cmi +0 -0
  72. package/lib/ocaml/EventLogStorage_Postgres_Ops-ReventlessPostgres.cmt +0 -0
  73. package/lib/ocaml/EventLogStorage_Postgres_Ops.ast +0 -0
  74. package/lib/ocaml/PgChangeFeed-ReventlessPostgres.cmi +0 -0
  75. package/lib/ocaml/PgChangeFeed-ReventlessPostgres.cmt +0 -0
  76. package/lib/ocaml/PgChangeFeed.ast +0 -0
  77. package/lib/ocaml/PgChangeFeed.res +6 -1
  78. package/lib/ocaml/PgDriver-ReventlessPostgres.cmi +0 -0
  79. package/lib/ocaml/PgDriver-ReventlessPostgres.cmt +0 -0
  80. package/lib/ocaml/PgDriver-ReventlessPostgres.cmti +0 -0
  81. package/lib/ocaml/PgDriver.ast +0 -0
  82. package/lib/ocaml/PgDriver.iast +0 -0
  83. package/lib/ocaml/PgSchema-ReventlessPostgres.cmi +0 -0
  84. package/lib/ocaml/PgSchema-ReventlessPostgres.cmt +0 -0
  85. package/lib/ocaml/PgSchema.ast +0 -0
  86. package/lib/ocaml/QueryDbStorage_Postgres-ReventlessPostgres.cmi +0 -0
  87. package/lib/ocaml/QueryDbStorage_Postgres-ReventlessPostgres.cmt +0 -0
  88. package/lib/ocaml/QueryDbStorage_Postgres.ast +0 -0
  89. package/lib/ocaml/QueryDbStorage_Postgres.res +1 -1
  90. package/lib/ocaml/QueryDbStorage_Postgres_Ops-ReventlessPostgres.cmi +0 -0
  91. package/lib/ocaml/QueryDbStorage_Postgres_Ops-ReventlessPostgres.cmt +0 -0
  92. package/lib/ocaml/QueryDbStorage_Postgres_Ops.ast +0 -0
  93. package/lib/ocaml/QueryEnginePostgres-ReventlessPostgres.cmi +0 -0
  94. package/lib/ocaml/QueryEnginePostgres-ReventlessPostgres.cmt +0 -0
  95. package/lib/ocaml/QueryEnginePostgres.ast +0 -0
  96. package/lib/ocaml/QueryEnginePostgres.res +26 -12
  97. package/lib/ocaml/ReventlessPostgres.cmt +0 -0
  98. package/package.json +11 -11
  99. package/rescript.json +2 -1
  100. package/src/EventLogChangeFeed.res +5 -2
  101. package/src/EventLogChangeFeed.res.mjs +3 -3
  102. package/src/PgChangeFeed.res +6 -1
  103. package/src/PgChangeFeed.res.mjs +6 -6
  104. package/src/QueryDbStorage_Postgres.res +1 -1
  105. package/src/QueryDbStorage_Postgres.res.mjs +1 -1
  106. package/src/QueryEnginePostgres.res +26 -12
  107. package/src/QueryEnginePostgres.res.mjs +26 -26
  108. package/lib/ocaml/PostgresIntegrationTest-ReventlessPostgres.cmi +0 -0
  109. package/lib/ocaml/PostgresIntegrationTest-ReventlessPostgres.cmj +0 -0
  110. package/lib/ocaml/PostgresIntegrationTest-ReventlessPostgres.cmt +0 -0
  111. package/lib/ocaml/PostgresIntegrationTest.ast +0 -0
  112. package/lib/ocaml/QueryEnginePostgresListPageTest-ReventlessPostgres.cmi +0 -0
  113. package/lib/ocaml/QueryEnginePostgresListPageTest-ReventlessPostgres.cmj +0 -0
  114. package/lib/ocaml/QueryEnginePostgresListPageTest-ReventlessPostgres.cmt +0 -0
  115. package/lib/ocaml/QueryEnginePostgresListPageTest.ast +0 -0
  116. package/tests/PostgresIntegrationTest.res.mjs +0 -377
  117. package/tests/QueryEnginePostgresListPageTest.res.mjs +0 -461
@@ -2,11 +2,10 @@
2
2
 
3
3
  import * as Stdlib_JSON from "@rescript/runtime/lib/es6/Stdlib_JSON.js";
4
4
  import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
5
- import * as Pulumi from "@pulumi/pulumi";
6
5
  import * as Stdlib_Nullable from "@rescript/runtime/lib/es6/Stdlib_Nullable.js";
7
6
  import * as PgDriver$ReventlessPostgres from "./PgDriver.res.mjs";
8
7
  import * as QueryDbListQuery$ReventlessCore from "@reventlessdev/reventless-core/src/components/Api/QueryDbListQuery.res.mjs";
9
- import * as QueryDbStorage_Postgres$ReventlessPostgres from "./QueryDbStorage_Postgres.res.mjs";
8
+ import * as QueryDbStorage_Postgres_Ops$ReventlessPostgres from "./QueryDbStorage_Postgres_Ops.res.mjs";
10
9
 
11
10
  function valueToText(v) {
12
11
  switch (v.TAG) {
@@ -105,25 +104,25 @@ function subIdSql(b, field, cmp, v) {
105
104
  }
106
105
 
107
106
  function decodeRow(withId, row) {
108
- let item = QueryDbStorage_Postgres$ReventlessPostgres.decodeItem(row);
107
+ let item = QueryDbStorage_Postgres_Ops$ReventlessPostgres.decodeItem(row);
109
108
  if (!withId) {
110
109
  return item;
111
110
  }
112
111
  let match = row["partition_key"];
113
112
  let pk = typeof match === "string" ? match : "";
114
- return QueryDbStorage_Postgres$ReventlessPostgres.withId(item, pk);
113
+ return QueryDbStorage_Postgres_Ops$ReventlessPostgres.withId(item, pk);
115
114
  }
116
115
 
117
116
  function Make(P) {
118
117
  let query = async (readModelName, key, id, subIdConfig, filterConfigs, ascending, limit) => {
119
- let table = QueryDbStorage_Postgres$ReventlessPostgres.tableName(readModelName);
118
+ let table = QueryDbStorage_Postgres_Ops$ReventlessPostgres.tableName(readModelName);
120
119
  let keyStr = key !== undefined ? key : valueToText(id);
121
120
  let b = {
122
121
  params: []
123
122
  };
124
123
  let where = [
125
124
  `partition_key = ` + param(b, keyStr),
126
- QueryDbStorage_Postgres$ReventlessPostgres.notExpiredClause
125
+ QueryDbStorage_Postgres_Ops$ReventlessPostgres.notExpiredClause
127
126
  ];
128
127
  if (subIdConfig !== undefined) {
129
128
  where.push(subIdSql(b, subIdConfig[0], subIdConfig[1], subIdConfig[2]));
@@ -137,11 +136,11 @@ function Make(P) {
137
136
  return (await PgDriver$ReventlessPostgres.query(P.pool, sql, b.params)).map(extra => decodeRow(false, extra));
138
137
  };
139
138
  let scan = async (readModelName, filterConfigs, limit) => {
140
- let table = QueryDbStorage_Postgres$ReventlessPostgres.tableName(readModelName);
139
+ let table = QueryDbStorage_Postgres_Ops$ReventlessPostgres.tableName(readModelName);
141
140
  let b = {
142
141
  params: []
143
142
  };
144
- let where = [QueryDbStorage_Postgres$ReventlessPostgres.notExpiredClause];
143
+ let where = [QueryDbStorage_Postgres_Ops$ReventlessPostgres.notExpiredClause];
145
144
  filterConfigs.forEach(param => {
146
145
  where.push(filterSql(b, param[0], param[1], param[2]));
147
146
  });
@@ -149,29 +148,29 @@ function Make(P) {
149
148
  return (await PgDriver$ReventlessPostgres.query(P.pool, sql, b.params)).map(extra => decodeRow(true, extra));
150
149
  };
151
150
  let indexLookup = async (readModelName, field, value) => {
152
- let table = QueryDbStorage_Postgres$ReventlessPostgres.tableName(readModelName);
151
+ let table = QueryDbStorage_Postgres_Ops$ReventlessPostgres.tableName(readModelName);
153
152
  let b = {
154
153
  params: []
155
154
  };
156
- let sql = `SELECT partition_key, item FROM ` + table + ` WHERE ` + col(field) + ` = ` + param(b, value) + ` AND ` + QueryDbStorage_Postgres$ReventlessPostgres.notExpiredClause;
155
+ let sql = `SELECT partition_key, item FROM ` + table + ` WHERE ` + col(field) + ` = ` + param(b, value) + ` AND ` + QueryDbStorage_Postgres_Ops$ReventlessPostgres.notExpiredClause;
157
156
  return (await PgDriver$ReventlessPostgres.query(P.pool, sql, b.params)).map(extra => decodeRow(true, extra));
158
157
  };
159
158
  let byIds = async (readModelName, ids) => {
160
159
  if (ids.length === 0) {
161
160
  return [];
162
161
  }
163
- let table = QueryDbStorage_Postgres$ReventlessPostgres.tableName(readModelName);
162
+ let table = QueryDbStorage_Postgres_Ops$ReventlessPostgres.tableName(readModelName);
164
163
  let b = {
165
164
  params: []
166
165
  };
167
166
  let idsJson = ids.map(prim => prim);
168
- let sql = `SELECT partition_key, item FROM ` + table + ` WHERE partition_key = ANY(` + param(b, idsJson) + `::text[]) AND ` + QueryDbStorage_Postgres$ReventlessPostgres.notExpiredClause;
167
+ let sql = `SELECT partition_key, item FROM ` + table + ` WHERE partition_key = ANY(` + param(b, idsJson) + `::text[]) AND ` + QueryDbStorage_Postgres_Ops$ReventlessPostgres.notExpiredClause;
169
168
  return (await PgDriver$ReventlessPostgres.query(P.pool, sql, b.params)).map(extra => decodeRow(true, extra));
170
169
  };
171
170
  let idExprC = `COALESCE(item->>'id', partition_key) COLLATE "C"`;
172
171
  let jsonTextC = field => col(field) + ` COLLATE "C"`;
173
- let listPage = async (readModelName, argsDict, capability, param$1) => {
174
- let table = QueryDbStorage_Postgres$ReventlessPostgres.tableName(readModelName);
172
+ let listPage = async (readModelName, argsDict, capability, param$1, ownerScope) => {
173
+ let table = QueryDbStorage_Postgres_Ops$ReventlessPostgres.tableName(readModelName);
175
174
  let filterDict = Stdlib_Option.getOr(Stdlib_Option.flatMap(argsDict["filter"], Stdlib_JSON.Decode.object), {});
176
175
  let strNonEmpty = k => Stdlib_Option.mapOr(Stdlib_Option.flatMap(filterDict[k], Stdlib_JSON.Decode.string), false, s => s.length > 0);
177
176
  let hasIds = Stdlib_Option.mapOr(Stdlib_Option.flatMap(filterDict["ids"], Stdlib_JSON.Decode.array), false, a => a.length !== 0);
@@ -183,7 +182,10 @@ function Make(P) {
183
182
  let b = {
184
183
  params: []
185
184
  };
186
- let whereParts = [QueryDbStorage_Postgres$ReventlessPostgres.notExpiredClause];
185
+ let whereParts = [QueryDbStorage_Postgres_Ops$ReventlessPostgres.notExpiredClause];
186
+ if (ownerScope !== undefined) {
187
+ whereParts.push(jsonTextC(ownerScope[0]) + ` = ` + param(b, ownerScope[1]));
188
+ }
187
189
  let valString = v => {
188
190
  let s = Stdlib_JSON.Decode.string(v);
189
191
  if (s !== undefined) {
@@ -232,8 +234,8 @@ function Make(P) {
232
234
  let cursorValueOf = item => Stdlib_Option.getOr(QueryDbListQuery$ReventlessCore.getFieldString(item, cursorField), QueryDbListQuery$ReventlessCore.getId(item));
233
235
  return QueryDbListQuery$ReventlessCore.buildConnection(pageItems, hasMore, false, cursorValueOf);
234
236
  };
235
- let itemsPage = async (readModelName, param$1, id, argsDict) => {
236
- let table = QueryDbStorage_Postgres$ReventlessPostgres.tableName(readModelName);
237
+ let itemsPage = async (readModelName, param$1, id, argsDict, ownerScope) => {
238
+ let table = QueryDbStorage_Postgres_Ops$ReventlessPostgres.tableName(readModelName);
237
239
  let filterDict = Stdlib_Option.getOr(Stdlib_Option.flatMap(argsDict["filter"], Stdlib_JSON.Decode.object), {});
238
240
  let fstr = k => Stdlib_Option.flatMap(filterDict[k], Stdlib_JSON.Decode.string);
239
241
  let orderDesc = Stdlib_Option.mapOr(fstr("order"), false, o => o === "DESC");
@@ -248,8 +250,11 @@ function Make(P) {
248
250
  };
249
251
  let where = [
250
252
  `partition_key = ` + param(b, id),
251
- QueryDbStorage_Postgres$ReventlessPostgres.notExpiredClause
253
+ QueryDbStorage_Postgres_Ops$ReventlessPostgres.notExpiredClause
252
254
  ];
255
+ if (ownerScope !== undefined) {
256
+ where.push(jsonTextC(ownerScope[0]) + ` = ` + param(b, ownerScope[1]));
257
+ }
253
258
  Stdlib_Option.forEach(fstr("prefix"), p => {
254
259
  where.push(`starts_with(sub_key, ` + param(b, p) + `)`);
255
260
  });
@@ -304,10 +309,6 @@ function Make(P) {
304
309
  }
305
310
  };
306
311
  };
307
- let make = _allQueryDbs => Pulumi.output({
308
- scan: scan,
309
- query: query
310
- });
311
312
  return {
312
313
  query: query,
313
314
  scan: scan,
@@ -316,12 +317,11 @@ function Make(P) {
316
317
  idExprC: idExprC,
317
318
  jsonTextC: jsonTextC,
318
319
  listPage: listPage,
319
- itemsPage: itemsPage,
320
- make: make
320
+ itemsPage: itemsPage
321
321
  };
322
322
  }
323
323
 
324
- let notExpired = QueryDbStorage_Postgres$ReventlessPostgres.notExpiredClause;
324
+ let notExpired = QueryDbStorage_Postgres_Ops$ReventlessPostgres.notExpiredClause;
325
325
 
326
326
  export {
327
327
  valueToText,
@@ -334,4 +334,4 @@ export {
334
334
  decodeRow,
335
335
  Make,
336
336
  }
337
- /* @pulumi/pulumi Not a pure module */
337
+ /* PgDriver-ReventlessPostgres Not a pure module */
@@ -1,377 +0,0 @@
1
- // Generated by ReScript, PLEASE EDIT WITH CARE
2
-
3
- import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
4
- import * as Primitive_object from "@rescript/runtime/lib/es6/Primitive_object.js";
5
- import * as Message$ReventlessCore from "@reventlessdev/reventless-core/src/Message.res.mjs";
6
- import * as PgDriver$ReventlessPostgres from "../src/PgDriver.res.mjs";
7
- import * as PgSchema$ReventlessPostgres from "../src/PgSchema.res.mjs";
8
- import * as PgChangeFeed$ReventlessPostgres from "../src/PgChangeFeed.res.mjs";
9
- import * as EventLogChangeFeed$ReventlessPostgres from "../src/EventLogChangeFeed.res.mjs";
10
- import * as EventLogStorage_Postgres$ReventlessPostgres from "../src/EventLogStorage_Postgres.res.mjs";
11
- import * as DcbEventLogStorage_Postgres$ReventlessPostgres from "../src/DcbEventLogStorage_Postgres.res.mjs";
12
-
13
- let opts = {};
14
-
15
- function jsonObj(pairs) {
16
- return Object.fromEntries(pairs);
17
- }
18
-
19
- function stored(eventType, tags, data) {
20
- return {
21
- eventType: eventType,
22
- data: data,
23
- tags: tags,
24
- meta: Message$ReventlessCore.generateMeta("pg-test", undefined, undefined, undefined, undefined, undefined, undefined, undefined)
25
- };
26
- }
27
-
28
- function evJson(msgId, v) {
29
- return Object.fromEntries([
30
- [
31
- "msgId",
32
- msgId
33
- ],
34
- [
35
- "v",
36
- v
37
- ]
38
- ]);
39
- }
40
-
41
- let url = process.env["PG_URL"];
42
-
43
- if (url !== undefined) {
44
- let pool = PgDriver$ReventlessPostgres.makePool({
45
- connectionString: url
46
- });
47
- globalThis.beforeAll(async () => {
48
- await PgSchema$ReventlessPostgres.ensureSchema(pool);
49
- return await PgSchema$ReventlessPostgres.truncateAll(pool);
50
- });
51
- globalThis.afterAll(() => {
52
- PgDriver$ReventlessPostgres.endPool(pool);
53
- });
54
- globalThis.describe("classic OCC event log", () => {
55
- globalThis.test("append, replay, and conflict on wrong seq", async () => {
56
- let match = EventLogStorage_Postgres$ReventlessPostgres.makeStorage(pool, "ct-orders", opts, undefined);
57
- let ops = match[1];
58
- let r0 = await ops.append(0, "agg-1", [
59
- evJson("m0", 1),
60
- evJson("m1", 2)
61
- ]);
62
- if (r0.TAG === "Ok") {
63
- globalThis.expect(true).toBe(true);
64
- } else {
65
- globalThis.expect("append").toBe("ok");
66
- }
67
- let rStale = await ops.append(0, "agg-1", [evJson("m2", 3)]);
68
- if (rStale.TAG === "Ok") {
69
- globalThis.expect("stale").toBe("conflict");
70
- } else {
71
- let tmp = rStale._0;
72
- if (typeof tmp !== "object") {
73
- globalThis.expect(true).toBe(true);
74
- } else {
75
- globalThis.expect("stale").toBe("conflict");
76
- }
77
- }
78
- let rGap = await ops.append(5, "agg-1", [evJson("m3", 4)]);
79
- if (rGap.TAG === "Ok") {
80
- globalThis.expect("gap").toBe("conflict");
81
- } else {
82
- let tmp$1 = rGap._0;
83
- if (typeof tmp$1 !== "object") {
84
- globalThis.expect(true).toBe(true);
85
- } else {
86
- globalThis.expect("gap").toBe("conflict");
87
- }
88
- }
89
- let rNext = await ops.append(2, "agg-1", [evJson("m4", 5)]);
90
- if (rNext.TAG === "Ok") {
91
- globalThis.expect(true).toBe(true);
92
- } else {
93
- globalThis.expect("next").toBe("ok");
94
- }
95
- let evs = await ops.replay("agg-1");
96
- globalThis.expect(evs.length).toBe(3);
97
- let rEmpty = await ops.append(3, "agg-1", []);
98
- if (rEmpty.TAG === "Ok") {
99
- globalThis.expect(true).toBe(true);
100
- return;
101
- }
102
- globalThis.expect("empty").toBe("ok");
103
- });
104
- });
105
- globalThis.describe("DCB event log", () => {
106
- let makeLog = name => DcbEventLogStorage_Postgres$ReventlessPostgres.makeStorage(pool, name, [], {
107
- TAG: "Simple",
108
- _0: {
109
- key: "k"
110
- }
111
- }, undefined, opts, undefined, undefined);
112
- globalThis.test("append + read round-trips events with tags", async () => {
113
- let match = makeLog("dcb-rt");
114
- let ops = match[1];
115
- let e1 = stored("ItemAdded", [{
116
- key: "itemId",
117
- value: "x1"
118
- }], Object.fromEntries([[
119
- "n",
120
- "w"
121
- ]]));
122
- let r = await ops.append([e1], undefined);
123
- if (r.TAG === "Ok") {
124
- globalThis.expect(true).toBe(true);
125
- } else {
126
- globalThis.expect(r._0).toBe("ok");
127
- }
128
- let read = await ops.read([], undefined);
129
- globalThis.expect(read.events.length).toBe(1);
130
- let first = read.events[0];
131
- globalThis.expect(first.eventType).toBe("ItemAdded");
132
- globalThis.expect(first.tags[0].key).toBe("itemId");
133
- globalThis.expect(first.tags[0].value).toBe("x1");
134
- });
135
- globalThis.test("conditional append conflicts when the boundary already has an event", async () => {
136
- let match = makeLog("dcb-cond");
137
- let ops = match[1];
138
- let mk = who => stored("Reserved", [{
139
- key: "seatId",
140
- value: "s1"
141
- }], Object.fromEntries([[
142
- "who",
143
- who
144
- ]]));
145
- let r1 = await ops.append([mk("a")], undefined);
146
- if (r1.TAG === "Ok") {
147
- globalThis.expect(true).toBe(true);
148
- } else {
149
- globalThis.expect("first").toBe("ok");
150
- }
151
- let cond_query = [{
152
- eventTypes: ["Reserved"],
153
- tags: [{
154
- key: "seatId",
155
- value: "s1"
156
- }]
157
- }];
158
- let cond = {
159
- query: cond_query
160
- };
161
- let r2 = await ops.append([mk("b")], cond);
162
- if (r2.TAG === "Ok") {
163
- globalThis.expect("second").toBe("conflict");
164
- return;
165
- }
166
- let tmp = r2._0;
167
- if (typeof tmp !== "object") {
168
- globalThis.expect(true).toBe(true);
169
- return;
170
- }
171
- globalThis.expect("second").toBe("conflict");
172
- });
173
- let writeSkew = (strategy, logName) => {
174
- globalThis.test(`write-skew: exactly one of two concurrent appends wins (` + logName + `)`, async () => {
175
- let match = DcbEventLogStorage_Postgres$ReventlessPostgres.makeStorage(pool, logName, [], {
176
- TAG: "Simple",
177
- _0: {
178
- key: "k"
179
- }
180
- }, undefined, opts, strategy, undefined);
181
- let ops = match[1];
182
- let cond_query = [{
183
- eventTypes: ["Reserved"],
184
- tags: [{
185
- key: "seatId",
186
- value: "hot"
187
- }]
188
- }];
189
- let cond = {
190
- query: cond_query
191
- };
192
- let mk = who => stored("Reserved", [{
193
- key: "seatId",
194
- value: "hot"
195
- }], Object.fromEntries([[
196
- "who",
197
- who
198
- ]]));
199
- let p1 = ops.append([mk("a")], cond);
200
- let p2 = ops.append([mk("b")], cond);
201
- let r1 = await p1;
202
- let r2 = await p2;
203
- let isOk = r => r.TAG === "Ok";
204
- let isConflict = r => Primitive_object.equal(r, {
205
- TAG: "Error",
206
- _0: "Conflict"
207
- });
208
- let oks = [
209
- r1,
210
- r2
211
- ].filter(isOk).length;
212
- let conflicts = [
213
- r1,
214
- r2
215
- ].filter(isConflict).length;
216
- globalThis.expect(oks).toBe(1);
217
- globalThis.expect(conflicts).toBe(1);
218
- let read = await ops.read([{
219
- tags: [{
220
- key: "seatId",
221
- value: "hot"
222
- }]
223
- }], undefined);
224
- globalThis.expect(read.events.length).toBe(1);
225
- });
226
- };
227
- writeSkew("AdvisoryLocks", "dcb-skew-advisory");
228
- writeSkew("RowLocks", "dcb-skew-rows");
229
- globalThis.test("hot tag: N concurrent conditional appends, exactly one wins", async () => {
230
- let match = makeLog("dcb-hot");
231
- let ops = match[1];
232
- let cond_query = [{
233
- eventTypes: ["Claimed"],
234
- tags: [{
235
- key: "prizeId",
236
- value: "p1"
237
- }]
238
- }];
239
- let cond = {
240
- query: cond_query
241
- };
242
- let promises = Stdlib_Array.make(12, 0).map((param, i) => ops.append([stored("Claimed", [{
243
- key: "prizeId",
244
- value: "p1"
245
- }], Object.fromEntries([[
246
- "who",
247
- i
248
- ]]))], cond));
249
- let results = await Promise.all(promises);
250
- let oks = results.filter(r => r.TAG === "Ok").length;
251
- globalThis.expect(oks).toBe(1);
252
- let read = await ops.read([{
253
- tags: [{
254
- key: "prizeId",
255
- value: "p1"
256
- }]
257
- }], undefined);
258
- globalThis.expect(read.events.length).toBe(1);
259
- });
260
- globalThis.test("cursors are monotonic and usable as `after`", async () => {
261
- let match = makeLog("dcb-cursor");
262
- let ops = match[1];
263
- let mk = i => stored("Tick", [{
264
- key: "streamId",
265
- value: "c1"
266
- }], Object.fromEntries([[
267
- "i",
268
- i
269
- ]]));
270
- await ops.append([mk(0)], undefined);
271
- let pos = await ops.append([mk(1)], undefined);
272
- let mid;
273
- mid = pos.TAG === "Ok" ? pos._0 : "";
274
- await ops.append([mk(2)], undefined);
275
- let read = await ops.read([{
276
- tags: [{
277
- key: "streamId",
278
- value: "c1"
279
- }]
280
- }], mid);
281
- globalThis.expect(read.events.length).toBe(1);
282
- globalThis.expect(read.events[0].eventType).toBe("Tick");
283
- });
284
- });
285
- globalThis.describe("change feed", () => {
286
- globalThis.test("drains all events and checkpoints", async () => {
287
- let match = DcbEventLogStorage_Postgres$ReventlessPostgres.makeStorage(pool, "feed-log", [], {
288
- TAG: "Simple",
289
- _0: {
290
- key: "k"
291
- }
292
- }, undefined, opts, undefined, undefined);
293
- let mk = i => stored("Fed", [{
294
- key: "id",
295
- value: "f"
296
- }], Object.fromEntries([[
297
- "i",
298
- i
299
- ]]));
300
- await match[1].append([
301
- mk(0),
302
- mk(1),
303
- mk(2)
304
- ], undefined);
305
- let collected = {
306
- contents: 0
307
- };
308
- let processed = await PgChangeFeed$ReventlessPostgres.drain(pool, "feed-log", "sub-1", undefined, async evs => {
309
- collected.contents = collected.contents + evs.length | 0;
310
- });
311
- globalThis.expect(processed).toBe(3);
312
- globalThis.expect(collected.contents).toBe(3);
313
- let again = await PgChangeFeed$ReventlessPostgres.drain(pool, "feed-log", "sub-1", undefined, async param => {});
314
- globalThis.expect(again).toBe(0);
315
- });
316
- });
317
- globalThis.describe("classic change feed (event_log, B2.5)", () => {
318
- globalThis.test("drains classic events in commit order, with fields, then checkpoints", async () => {
319
- let match = EventLogStorage_Postgres$ReventlessPostgres.makeStorage(pool, "cf-orders", opts, undefined);
320
- let ops = match[1];
321
- await ops.append(0, "agg-1", [
322
- evJson("m0", 1),
323
- evJson("m1", 2)
324
- ]);
325
- await ops.append(0, "agg-2", [evJson("m2", 3)]);
326
- let collected = {
327
- contents: []
328
- };
329
- let processed = await EventLogChangeFeed$ReventlessPostgres.drain(pool, "cf-orders", "cf-sub", undefined, async evs => {
330
- collected.contents = collected.contents.concat(evs);
331
- });
332
- globalThis.expect(processed).toBe(3);
333
- globalThis.expect(collected.contents.length).toBe(3);
334
- let first = collected.contents[0];
335
- globalThis.expect(first.aggregateId).toBe("agg-1");
336
- globalThis.expect(first.seqNr).toBe(0);
337
- globalThis.expect(first.msgId).toEqual("m0");
338
- let cursors = collected.contents.map(e => e.cursor);
339
- let increasing = true;
340
- for (let i = 1, i_finish = cursors.length; i < i_finish; ++i) {
341
- if (cursors[i] <= cursors[i - 1 | 0]) {
342
- increasing = false;
343
- }
344
- }
345
- globalThis.expect(increasing).toBe(true);
346
- let again = await EventLogChangeFeed$ReventlessPostgres.drain(pool, "cf-orders", "cf-sub", undefined, async param => {});
347
- globalThis.expect(again).toBe(0);
348
- });
349
- globalThis.test("concurrent appends across aggregates: every event drained exactly once", async () => {
350
- let match = EventLogStorage_Postgres$ReventlessPostgres.makeStorage(pool, "cf-concurrent", opts, undefined);
351
- let ops = match[1];
352
- let promises = Stdlib_Array.make(20, 0).map((param, i) => ops.append(0, "agg-" + i.toString(), [evJson("m" + i.toString(), i)]));
353
- await Promise.all(promises);
354
- let collected = {
355
- contents: []
356
- };
357
- await EventLogChangeFeed$ReventlessPostgres.drain(pool, "cf-concurrent", "cf-conc-sub", undefined, async evs => {
358
- collected.contents = collected.contents.concat(evs);
359
- });
360
- globalThis.expect(collected.contents.length).toBe(20);
361
- let distinctCursors = new Set(collected.contents.map(e => e.cursor));
362
- globalThis.expect(distinctCursors.size).toBe(20);
363
- });
364
- });
365
- } else {
366
- globalThis.test("Postgres integration (skipped — set PG_URL to run)", () => {
367
- globalThis.expect(true).toBe(true);
368
- });
369
- }
370
-
371
- export {
372
- opts,
373
- jsonObj,
374
- stored,
375
- evJson,
376
- }
377
- /* url Not a pure module */