@volter/world-core 3.0.140 → 3.0.141
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/dist/src/head.js +9 -2
- package/package.json +1 -1
- package/src/head.ts +8 -2
package/dist/src/head.js
CHANGED
|
@@ -323,12 +323,19 @@ async function performNow(opts) {
|
|
|
323
323
|
const adapters = opts.adapters ?? stateSystemFor(vendor) ?? stateSystemFor(service);
|
|
324
324
|
if (!adapters?.perform)
|
|
325
325
|
throw new Error(`the ${vendor} twin has no perform adapter — a pack names one in its descriptor and registers itself (registerPack)`);
|
|
326
|
+
const settling = settlingEntries(service, root);
|
|
327
|
+
const selected = opts.actionIds === undefined ? undefined : new Set(opts.actionIds);
|
|
328
|
+
const pick = (list) => selected === undefined ? list : list.filter((action) => selected.has(action.id));
|
|
329
|
+
if (selected !== undefined) {
|
|
330
|
+
const last = settling.offered.reduce((index, action, at) => selected.has(action.id) ? at : index, -1);
|
|
331
|
+
const earlier = settling.offered.slice(0, last + 1).find((action) => !selected.has(action.id));
|
|
332
|
+
if (earlier)
|
|
333
|
+
throw new Error(`the ${service} twin has an earlier undeployed entry (${earlier.operation ?? earlier.subject.type}, ${earlier.id}); deploy its changeset first. Selected deployment cannot skip earlier writes on the same vendor.`);
|
|
334
|
+
}
|
|
326
335
|
// the caller's executor, or the one built over the sealed credential; an unsealed root has no other
|
|
327
336
|
const execute = opts.execute ?? buildRemoteExecute(validateRemoteOrigin(bound.sealed.url, { allowInsecureLoopback: true }), await openRootCredential(bound.sealed, vendor), authStrategyFor(vendor), getPack(vendor)?.hosts, { custody: rootCustody(bound.sealed, vendor), vendor });
|
|
328
337
|
// an unsealed root's World is where its state resolves (the root given, PROJECT_ROOT, or the working directory)
|
|
329
338
|
const checks = opts.checks ?? (await loadChecks(bound.sealed ? worldRootOf(bound.sealed) : worldPaths(service, root).root));
|
|
330
|
-
const settling = settlingEntries(service, root);
|
|
331
|
-
const pick = (list) => (opts.actionIds === undefined ? list : opts.actionIds.map((id) => list.find((a) => a.id === id)).filter((a) => a !== undefined));
|
|
332
339
|
const report = { pushed: 0, deployed: [], skipped: [], replayed: [], worldOnly: pick(settling.worldOnly).map((e) => e.id) };
|
|
333
340
|
if (opts.actionIds) {
|
|
334
341
|
const settled = receiptsByEntry(parentEntries(service, root));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volter/world-core",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.141",
|
|
4
4
|
"description": "The kernel of Volter World: one log per twin, branches as pointers, checkpoints, the fold that keeps a twin current, the head that performs a write against the vendor, references, and the git plane. A twin package builds on it; the runtime serves it.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"twin",
|
package/src/head.ts
CHANGED
|
@@ -355,12 +355,18 @@ async function performNow(opts: Parameters<typeof performEntries>[0]): Promise<D
|
|
|
355
355
|
const vendor = bound.vendor;
|
|
356
356
|
const adapters = opts.adapters ?? stateSystemFor(vendor) ?? stateSystemFor(service);
|
|
357
357
|
if (!adapters?.perform) throw new Error(`the ${vendor} twin has no perform adapter — a pack names one in its descriptor and registers itself (registerPack)`);
|
|
358
|
+
const settling = settlingEntries(service, root);
|
|
359
|
+
const selected = opts.actionIds === undefined ? undefined : new Set(opts.actionIds);
|
|
360
|
+
const pick = (list: TwinAction[]): TwinAction[] => selected === undefined ? list : list.filter((action) => selected.has(action.id));
|
|
361
|
+
if (selected !== undefined) {
|
|
362
|
+
const last = settling.offered.reduce((index, action, at) => selected.has(action.id) ? at : index, -1);
|
|
363
|
+
const earlier = settling.offered.slice(0, last + 1).find((action) => !selected.has(action.id));
|
|
364
|
+
if (earlier) throw new Error(`the ${service} twin has an earlier undeployed entry (${earlier.operation ?? earlier.subject.type}, ${earlier.id}); deploy its changeset first. Selected deployment cannot skip earlier writes on the same vendor.`);
|
|
365
|
+
}
|
|
358
366
|
// the caller's executor, or the one built over the sealed credential; an unsealed root has no other
|
|
359
367
|
const execute = opts.execute ?? buildRemoteExecute(validateRemoteOrigin(bound.sealed!.url, { allowInsecureLoopback: true }), await openRootCredential(bound.sealed!, vendor), authStrategyFor(vendor), getPack(vendor)?.hosts, { custody: rootCustody(bound.sealed!, vendor), vendor });
|
|
360
368
|
// an unsealed root's World is where its state resolves (the root given, PROJECT_ROOT, or the working directory)
|
|
361
369
|
const checks = opts.checks ?? (await loadChecks(bound.sealed ? worldRootOf(bound.sealed) : worldPaths(service, root).root));
|
|
362
|
-
const settling = settlingEntries(service, root);
|
|
363
|
-
const pick = (list: TwinAction[]): TwinAction[] => (opts.actionIds === undefined ? list : opts.actionIds.map((id) => list.find((a) => a.id === id)).filter((a): a is TwinAction => a !== undefined));
|
|
364
370
|
const report: DeployReport = { pushed: 0, deployed: [], skipped: [], replayed: [], worldOnly: pick(settling.worldOnly).map((e) => e.id) };
|
|
365
371
|
if (opts.actionIds) {
|
|
366
372
|
const settled = receiptsByEntry(parentEntries(service, root));
|