@reventlessdev/reventless-seed 1.0.0-alpha.3 → 1.0.0-alpha.4
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.
- package/CHANGELOG.md +7 -0
- package/lib/bs/.compiler.log +2 -2
- package/lib/bs/compiler-info.json +1 -1
- package/lib/bs/src/Seed-ReventlessSeed.cmi +0 -0
- package/lib/bs/src/Seed-ReventlessSeed.cmt +0 -0
- package/lib/bs/src/Seed_Client-ReventlessSeed.cmi +0 -0
- package/lib/bs/src/Seed_Client-ReventlessSeed.cmj +0 -0
- package/lib/bs/src/Seed_Client-ReventlessSeed.cmt +0 -0
- package/lib/bs/src/Seed_Client.ast +0 -0
- package/lib/bs/src/Seed_Client.res +36 -0
- package/lib/bs/src/Seed_Client.res.mjs +23 -0
- package/lib/bs/src/Seed_Connect-ReventlessSeed.cmi +0 -0
- package/lib/bs/src/Seed_Connect-ReventlessSeed.cmt +0 -0
- package/lib/bs/src/Seed_Runner-ReventlessSeed.cmi +0 -0
- package/lib/bs/src/Seed_Runner-ReventlessSeed.cmt +0 -0
- package/lib/ocaml/.compiler.log +2 -2
- package/lib/ocaml/Seed-ReventlessSeed.cmi +0 -0
- package/lib/ocaml/Seed-ReventlessSeed.cmt +0 -0
- package/lib/ocaml/Seed_Client-ReventlessSeed.cmi +0 -0
- package/lib/ocaml/Seed_Client-ReventlessSeed.cmj +0 -0
- package/lib/ocaml/Seed_Client-ReventlessSeed.cmt +0 -0
- package/lib/ocaml/Seed_Client.ast +0 -0
- package/lib/ocaml/Seed_Client.res +36 -0
- package/lib/ocaml/Seed_Connect-ReventlessSeed.cmi +0 -0
- package/lib/ocaml/Seed_Connect-ReventlessSeed.cmt +0 -0
- package/lib/ocaml/Seed_Runner-ReventlessSeed.cmi +0 -0
- package/lib/ocaml/Seed_Runner-ReventlessSeed.cmt +0 -0
- package/package.json +1 -1
- package/src/Seed_Client.res +36 -0
- package/src/Seed_Client.res.mjs +23 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,13 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# 1.0.0-alpha.4 (2026-07-27)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* **seed:** guarded AWS store reset (seed:reset) with per-project scope selection ([8446172](https://github.com/ReventlessDev/reventless-core/commit/8446172cbb53776a58f53220d19e96d96ce94508))
|
|
11
|
+
|
|
12
|
+
|
|
6
13
|
# 1.0.0-alpha.3 (2026-07-27)
|
|
7
14
|
|
|
8
15
|
### Features
|
package/lib/bs/.compiler.log
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
#Start(
|
|
2
|
-
#Done(
|
|
1
|
+
#Start(1785181007705)
|
|
2
|
+
#Done(1785181012323)
|
|
@@ -4,5 +4,5 @@
|
|
|
4
4
|
"bsc_hash": "75e3a59c95cc953608fd3dd6ea6ed68141bba4414a20a52f114261b8a48385fa",
|
|
5
5
|
"rescript_config_hash": "ad3a9d479584c1d6e4fe10cd993d9e290f74732e9b0cb3dd5d7429e88b4bba38",
|
|
6
6
|
"runtime_path": "/home/runner/work/reventless-core/reventless-core/node_modules/@rescript/runtime",
|
|
7
|
-
"generated_at": "
|
|
7
|
+
"generated_at": "1785181012338"
|
|
8
8
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -216,6 +216,42 @@ let queryAllNodes = async (t: t, ~field as fieldName: string, ~selection: string
|
|
|
216
216
|
let countNodes = async (t: t, ~field: string): int =>
|
|
217
217
|
(await queryAllNodes(t, ~field, ~selection="id"))->Array.length
|
|
218
218
|
|
|
219
|
+
/**
|
|
220
|
+
* Polls a connection field until the collected nodes satisfy `satisfied`, or the
|
|
221
|
+
* timeout elapses. Read models are eventually consistent: a view queried the
|
|
222
|
+
* instant after the writes that feed it can still read empty or partial (a
|
|
223
|
+
* DynamoDB connection scan is eventually consistent by default, and the write and
|
|
224
|
+
* read-back can land on different replicas), so a cross-check that asserts on a
|
|
225
|
+
* single immediate read races the projection. Same rationale as `waitForIds`,
|
|
226
|
+
* for the "observe the whole connection" case rather than a fixed id set.
|
|
227
|
+
*
|
|
228
|
+
* On timeout, throws `Failed(onTimeout(finalNodes))` so the caller can report
|
|
229
|
+
* what the view actually settled on — distinguishing a still-empty view from a
|
|
230
|
+
* genuine count mismatch — instead of a bare assertion.
|
|
231
|
+
*/
|
|
232
|
+
let queryAllNodesUntil = async (
|
|
233
|
+
t: t,
|
|
234
|
+
~field: string,
|
|
235
|
+
~selection: string,
|
|
236
|
+
~satisfied: array<JSON.t> => bool,
|
|
237
|
+
~onTimeout: array<JSON.t> => string,
|
|
238
|
+
~timeoutMs: int=60000,
|
|
239
|
+
): array<JSON.t> => {
|
|
240
|
+
let deadline = nowMs() +. Int.toFloat(timeoutMs)
|
|
241
|
+
let result = ref(None)
|
|
242
|
+
while result.contents == None {
|
|
243
|
+
let nodes = await queryAllNodes(t, ~field, ~selection)
|
|
244
|
+
if satisfied(nodes) {
|
|
245
|
+
result := Some(nodes)
|
|
246
|
+
} else if nowMs() > deadline {
|
|
247
|
+
throw(Failed(onTimeout(nodes)))
|
|
248
|
+
} else {
|
|
249
|
+
await sleep(500)
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
result.contents->Option.getOr([])
|
|
253
|
+
}
|
|
254
|
+
|
|
219
255
|
/**
|
|
220
256
|
* Polls a `<View>ByIds` field until every id is present.
|
|
221
257
|
*
|
|
@@ -208,6 +208,28 @@ async function countNodes(t, field) {
|
|
|
208
208
|
return (await queryAllNodes(t, field, "id")).length;
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
+
async function queryAllNodesUntil(t, field, selection, satisfied, onTimeout, timeoutMsOpt) {
|
|
212
|
+
let timeoutMs = timeoutMsOpt !== undefined ? timeoutMsOpt : 60000;
|
|
213
|
+
let deadline = Date.now() + timeoutMs;
|
|
214
|
+
let result;
|
|
215
|
+
while (result === undefined) {
|
|
216
|
+
let nodes = await queryAllNodes(t, field, selection);
|
|
217
|
+
if (satisfied(nodes)) {
|
|
218
|
+
result = nodes;
|
|
219
|
+
} else {
|
|
220
|
+
if (Date.now() > deadline) {
|
|
221
|
+
throw {
|
|
222
|
+
RE_EXN_ID: Seed_Types$ReventlessSeed.Failed,
|
|
223
|
+
_1: onTimeout(nodes),
|
|
224
|
+
Error: new Error()
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
await sleep(500);
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
return Stdlib_Option.getOr(result, []);
|
|
231
|
+
}
|
|
232
|
+
|
|
211
233
|
async function waitForIds(t, fieldName, ids, timeoutMsOpt) {
|
|
212
234
|
let timeoutMs = timeoutMsOpt !== undefined ? timeoutMsOpt : 60000;
|
|
213
235
|
let deadline = Date.now() + timeoutMs;
|
|
@@ -255,6 +277,7 @@ export {
|
|
|
255
277
|
sendAll,
|
|
256
278
|
queryAllNodes,
|
|
257
279
|
countNodes,
|
|
280
|
+
queryAllNodesUntil,
|
|
258
281
|
waitForIds,
|
|
259
282
|
}
|
|
260
283
|
/* No side effect */
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/lib/ocaml/.compiler.log
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
#Start(
|
|
2
|
-
#Done(
|
|
1
|
+
#Start(1785181007705)
|
|
2
|
+
#Done(1785181012323)
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -216,6 +216,42 @@ let queryAllNodes = async (t: t, ~field as fieldName: string, ~selection: string
|
|
|
216
216
|
let countNodes = async (t: t, ~field: string): int =>
|
|
217
217
|
(await queryAllNodes(t, ~field, ~selection="id"))->Array.length
|
|
218
218
|
|
|
219
|
+
/**
|
|
220
|
+
* Polls a connection field until the collected nodes satisfy `satisfied`, or the
|
|
221
|
+
* timeout elapses. Read models are eventually consistent: a view queried the
|
|
222
|
+
* instant after the writes that feed it can still read empty or partial (a
|
|
223
|
+
* DynamoDB connection scan is eventually consistent by default, and the write and
|
|
224
|
+
* read-back can land on different replicas), so a cross-check that asserts on a
|
|
225
|
+
* single immediate read races the projection. Same rationale as `waitForIds`,
|
|
226
|
+
* for the "observe the whole connection" case rather than a fixed id set.
|
|
227
|
+
*
|
|
228
|
+
* On timeout, throws `Failed(onTimeout(finalNodes))` so the caller can report
|
|
229
|
+
* what the view actually settled on — distinguishing a still-empty view from a
|
|
230
|
+
* genuine count mismatch — instead of a bare assertion.
|
|
231
|
+
*/
|
|
232
|
+
let queryAllNodesUntil = async (
|
|
233
|
+
t: t,
|
|
234
|
+
~field: string,
|
|
235
|
+
~selection: string,
|
|
236
|
+
~satisfied: array<JSON.t> => bool,
|
|
237
|
+
~onTimeout: array<JSON.t> => string,
|
|
238
|
+
~timeoutMs: int=60000,
|
|
239
|
+
): array<JSON.t> => {
|
|
240
|
+
let deadline = nowMs() +. Int.toFloat(timeoutMs)
|
|
241
|
+
let result = ref(None)
|
|
242
|
+
while result.contents == None {
|
|
243
|
+
let nodes = await queryAllNodes(t, ~field, ~selection)
|
|
244
|
+
if satisfied(nodes) {
|
|
245
|
+
result := Some(nodes)
|
|
246
|
+
} else if nowMs() > deadline {
|
|
247
|
+
throw(Failed(onTimeout(nodes)))
|
|
248
|
+
} else {
|
|
249
|
+
await sleep(500)
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
result.contents->Option.getOr([])
|
|
253
|
+
}
|
|
254
|
+
|
|
219
255
|
/**
|
|
220
256
|
* Polls a `<View>ByIds` field until every id is present.
|
|
221
257
|
*
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
package/src/Seed_Client.res
CHANGED
|
@@ -216,6 +216,42 @@ let queryAllNodes = async (t: t, ~field as fieldName: string, ~selection: string
|
|
|
216
216
|
let countNodes = async (t: t, ~field: string): int =>
|
|
217
217
|
(await queryAllNodes(t, ~field, ~selection="id"))->Array.length
|
|
218
218
|
|
|
219
|
+
/**
|
|
220
|
+
* Polls a connection field until the collected nodes satisfy `satisfied`, or the
|
|
221
|
+
* timeout elapses. Read models are eventually consistent: a view queried the
|
|
222
|
+
* instant after the writes that feed it can still read empty or partial (a
|
|
223
|
+
* DynamoDB connection scan is eventually consistent by default, and the write and
|
|
224
|
+
* read-back can land on different replicas), so a cross-check that asserts on a
|
|
225
|
+
* single immediate read races the projection. Same rationale as `waitForIds`,
|
|
226
|
+
* for the "observe the whole connection" case rather than a fixed id set.
|
|
227
|
+
*
|
|
228
|
+
* On timeout, throws `Failed(onTimeout(finalNodes))` so the caller can report
|
|
229
|
+
* what the view actually settled on — distinguishing a still-empty view from a
|
|
230
|
+
* genuine count mismatch — instead of a bare assertion.
|
|
231
|
+
*/
|
|
232
|
+
let queryAllNodesUntil = async (
|
|
233
|
+
t: t,
|
|
234
|
+
~field: string,
|
|
235
|
+
~selection: string,
|
|
236
|
+
~satisfied: array<JSON.t> => bool,
|
|
237
|
+
~onTimeout: array<JSON.t> => string,
|
|
238
|
+
~timeoutMs: int=60000,
|
|
239
|
+
): array<JSON.t> => {
|
|
240
|
+
let deadline = nowMs() +. Int.toFloat(timeoutMs)
|
|
241
|
+
let result = ref(None)
|
|
242
|
+
while result.contents == None {
|
|
243
|
+
let nodes = await queryAllNodes(t, ~field, ~selection)
|
|
244
|
+
if satisfied(nodes) {
|
|
245
|
+
result := Some(nodes)
|
|
246
|
+
} else if nowMs() > deadline {
|
|
247
|
+
throw(Failed(onTimeout(nodes)))
|
|
248
|
+
} else {
|
|
249
|
+
await sleep(500)
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
result.contents->Option.getOr([])
|
|
253
|
+
}
|
|
254
|
+
|
|
219
255
|
/**
|
|
220
256
|
* Polls a `<View>ByIds` field until every id is present.
|
|
221
257
|
*
|
package/src/Seed_Client.res.mjs
CHANGED
|
@@ -208,6 +208,28 @@ async function countNodes(t, field) {
|
|
|
208
208
|
return (await queryAllNodes(t, field, "id")).length;
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
+
async function queryAllNodesUntil(t, field, selection, satisfied, onTimeout, timeoutMsOpt) {
|
|
212
|
+
let timeoutMs = timeoutMsOpt !== undefined ? timeoutMsOpt : 60000;
|
|
213
|
+
let deadline = Date.now() + timeoutMs;
|
|
214
|
+
let result;
|
|
215
|
+
while (result === undefined) {
|
|
216
|
+
let nodes = await queryAllNodes(t, field, selection);
|
|
217
|
+
if (satisfied(nodes)) {
|
|
218
|
+
result = nodes;
|
|
219
|
+
} else {
|
|
220
|
+
if (Date.now() > deadline) {
|
|
221
|
+
throw {
|
|
222
|
+
RE_EXN_ID: Seed_Types$ReventlessSeed.Failed,
|
|
223
|
+
_1: onTimeout(nodes),
|
|
224
|
+
Error: new Error()
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
await sleep(500);
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
return Stdlib_Option.getOr(result, []);
|
|
231
|
+
}
|
|
232
|
+
|
|
211
233
|
async function waitForIds(t, fieldName, ids, timeoutMsOpt) {
|
|
212
234
|
let timeoutMs = timeoutMsOpt !== undefined ? timeoutMsOpt : 60000;
|
|
213
235
|
let deadline = Date.now() + timeoutMs;
|
|
@@ -255,6 +277,7 @@ export {
|
|
|
255
277
|
sendAll,
|
|
256
278
|
queryAllNodes,
|
|
257
279
|
countNodes,
|
|
280
|
+
queryAllNodesUntil,
|
|
258
281
|
waitForIds,
|
|
259
282
|
}
|
|
260
283
|
/* No side effect */
|