@volter/world-core 3.0.104 → 3.0.106
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.
|
@@ -211,14 +211,16 @@ export type ResourceDecl = {
|
|
|
211
211
|
partial?: string[];
|
|
212
212
|
};
|
|
213
213
|
/** fields that count this subject's children (an App's `installations_count`): the live subjects of `of` whose `by`
|
|
214
|
-
* holds this one's id (or vendor `parentKey`), only those with `present` set
|
|
214
|
+
* holds this one's id (or vendor `parentKey`), only those with `present` set or `absent` unset when named and without
|
|
215
215
|
* any matching `unless` field, plus `plus` (a customer's
|
|
216
|
-
* `next_invoice_sequence` is one past its numbered invoices).
|
|
216
|
+
* `next_invoice_sequence` is one past its numbered invoices). `by` may be a dot path; exact field names take
|
|
217
|
+
* precedence. The kernel keeps each whenever a child is written. */
|
|
217
218
|
counts?: Record<string, {
|
|
218
219
|
of: string;
|
|
219
220
|
by: string;
|
|
220
221
|
parentKey?: string;
|
|
221
222
|
present?: string;
|
|
223
|
+
absent?: string;
|
|
222
224
|
unless?: Record<string, unknown>;
|
|
223
225
|
plus?: number;
|
|
224
226
|
}>;
|
package/dist/src/derived-core.js
CHANGED
|
@@ -756,15 +756,18 @@ async function finishWrite(m, call, resource, row, result, operation, params, ro
|
|
|
756
756
|
async function keepCounts(m, call, resource, row, params, root, occurredAt) {
|
|
757
757
|
for (const [parent, decl] of Object.entries(m.resources)) {
|
|
758
758
|
for (const [field, c] of Object.entries(decl.counts ?? {})) {
|
|
759
|
-
if (storedType(m, c.of) !== storedType(m, resource)
|
|
759
|
+
if (storedType(m, c.of) !== storedType(m, resource))
|
|
760
760
|
continue;
|
|
761
|
-
const
|
|
761
|
+
const parentId = parentField(row, c.by);
|
|
762
|
+
if (parentId === undefined || parentId === null)
|
|
763
|
+
continue;
|
|
764
|
+
const pid = String(parentId);
|
|
762
765
|
const held = stored(m, parent, root).find((r) => String(c.parentKey ? ownFields(r)[c.parentKey] : r.id) === pid);
|
|
763
766
|
if (!held)
|
|
764
767
|
continue;
|
|
765
768
|
const n = stored(m, c.of, root).filter((r) => {
|
|
766
769
|
const x = r;
|
|
767
|
-
return String(x
|
|
770
|
+
return String(parentField(x, c.by)) === pid && (c.present === undefined || (x[c.present] !== undefined && x[c.present] !== null)) && (c.absent === undefined || parentField(ownFields(r), c.absent) === undefined || parentField(ownFields(r), c.absent) === null) && Object.entries(c.unless ?? {}).every(([key, value]) => ownFields(r)[key] !== value);
|
|
768
771
|
}).length + (c.plus ?? 0);
|
|
769
772
|
if (held[field] !== n)
|
|
770
773
|
await writeDetailed(m, call, parent, String(held.id), { [field]: n }, `${storedType(m, parent)}.counted`, params, root, occurredAt);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volter/world-core",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.106",
|
|
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/derived-core.ts
CHANGED
|
@@ -194,10 +194,11 @@ export type ResourceDecl = {
|
|
|
194
194
|
* substring, case-insensitively */
|
|
195
195
|
search?: { param: string; exact?: string[]; partial?: string[] };
|
|
196
196
|
/** fields that count this subject's children (an App's `installations_count`): the live subjects of `of` whose `by`
|
|
197
|
-
* holds this one's id (or vendor `parentKey`), only those with `present` set
|
|
197
|
+
* holds this one's id (or vendor `parentKey`), only those with `present` set or `absent` unset when named and without
|
|
198
198
|
* any matching `unless` field, plus `plus` (a customer's
|
|
199
|
-
* `next_invoice_sequence` is one past its numbered invoices).
|
|
200
|
-
|
|
199
|
+
* `next_invoice_sequence` is one past its numbered invoices). `by` may be a dot path; exact field names take
|
|
200
|
+
* precedence. The kernel keeps each whenever a child is written. */
|
|
201
|
+
counts?: Record<string, { of: string; by: string; parentKey?: string; present?: string; absent?: string; unless?: Record<string, unknown>; plus?: number }>;
|
|
201
202
|
/** how the vendor's state of this type is read back into a root (the real-system adapters, "Refresh"): the list that
|
|
202
203
|
* enumerates it (once per parent, under `parent`; `complete: false` when it is not the whole type; `items`, the answer's
|
|
203
204
|
* path to them, when the spec does not name the list it answers), the one read of a singleton, or `none` with why the
|
|
@@ -1233,13 +1234,15 @@ async function finishWrite(m: DerivedManifest, call: DerivedCall, resource: stri
|
|
|
1233
1234
|
async function keepCounts(m: DerivedManifest, call: DerivedCall, resource: string, row: Record<string, unknown>, params: Record<string, unknown>, root: string | undefined, occurredAt: string): Promise<void> {
|
|
1234
1235
|
for (const [parent, decl] of Object.entries(m.resources)) {
|
|
1235
1236
|
for (const [field, c] of Object.entries(decl.counts ?? {})) {
|
|
1236
|
-
if (storedType(m, c.of) !== storedType(m, resource)
|
|
1237
|
-
const
|
|
1237
|
+
if (storedType(m, c.of) !== storedType(m, resource)) continue;
|
|
1238
|
+
const parentId = parentField(row, c.by);
|
|
1239
|
+
if (parentId === undefined || parentId === null) continue;
|
|
1240
|
+
const pid = String(parentId);
|
|
1238
1241
|
const held = stored(m, parent, root).find((r) => String(c.parentKey ? ownFields(r)[c.parentKey] : r.id) === pid) as Record<string, unknown> | undefined;
|
|
1239
1242
|
if (!held) continue;
|
|
1240
1243
|
const n = stored(m, c.of, root).filter((r) => {
|
|
1241
1244
|
const x = r as Record<string, unknown>;
|
|
1242
|
-
return String(x
|
|
1245
|
+
return String(parentField(x, c.by)) === pid && (c.present === undefined || (x[c.present] !== undefined && x[c.present] !== null)) && (c.absent === undefined || parentField(ownFields(r), c.absent) === undefined || parentField(ownFields(r), c.absent) === null) && Object.entries(c.unless ?? {}).every(([key, value]) => ownFields(r)[key] !== value);
|
|
1243
1246
|
}).length + (c.plus ?? 0);
|
|
1244
1247
|
if (held[field] !== n) await writeDetailed(m, call, parent, String(held.id), { [field]: n }, `${storedType(m, parent)}.counted`, params, root, occurredAt);
|
|
1245
1248
|
}
|