@x12i/memorix-service 3.12.4 → 3.13.0
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/README.md +1 -1
- package/dist/anomaly/catalog.d.ts +4 -0
- package/dist/anomaly/catalog.d.ts.map +1 -0
- package/dist/anomaly/catalog.js +315 -0
- package/dist/anomaly/catalog.js.map +1 -0
- package/dist/anomaly/descriptors.d.ts +11 -0
- package/dist/anomaly/descriptors.d.ts.map +1 -0
- package/dist/anomaly/descriptors.js +113 -0
- package/dist/anomaly/descriptors.js.map +1 -0
- package/dist/anomaly/index.d.ts +6 -0
- package/dist/anomaly/index.d.ts.map +1 -0
- package/dist/anomaly/index.js +5 -0
- package/dist/anomaly/index.js.map +1 -0
- package/dist/anomaly/records.d.ts +28 -0
- package/dist/anomaly/records.d.ts.map +1 -0
- package/dist/anomaly/records.js +384 -0
- package/dist/anomaly/records.js.map +1 -0
- package/dist/anomaly/types.d.ts +116 -0
- package/dist/anomaly/types.d.ts.map +1 -0
- package/dist/anomaly/types.js +24 -0
- package/dist/anomaly/types.js.map +1 -0
- package/dist/anomaly/values.d.ts +31 -0
- package/dist/anomaly/values.d.ts.map +1 -0
- package/dist/anomaly/values.js +171 -0
- package/dist/anomaly/values.js.map +1 -0
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +12 -0
- package/dist/app.js.map +1 -1
- package/dist/catalog-bridge.d.ts +18 -0
- package/dist/catalog-bridge.d.ts.map +1 -1
- package/dist/catalog-bridge.js +85 -0
- package/dist/catalog-bridge.js.map +1 -1
- package/dist/errors.d.ts +5 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +18 -0
- package/dist/errors.js.map +1 -1
- package/dist/knowledge-upstream.d.ts +32 -0
- package/dist/knowledge-upstream.d.ts.map +1 -1
- package/dist/knowledge-upstream.js +86 -2
- package/dist/knowledge-upstream.js.map +1 -1
- package/dist/mcp/nexum-tools.d.ts +1 -1
- package/dist/mcp/nexum-tools.d.ts.map +1 -1
- package/dist/mcp/nexum-tools.js +39 -22
- package/dist/mcp/nexum-tools.js.map +1 -1
- package/dist/nexum-analysis/enqueue.d.ts.map +1 -1
- package/dist/nexum-analysis/enqueue.js +2 -1
- package/dist/nexum-analysis/enqueue.js.map +1 -1
- package/dist/nexum-analysis/knowledge-read.d.ts +45 -0
- package/dist/nexum-analysis/knowledge-read.d.ts.map +1 -0
- package/dist/nexum-analysis/knowledge-read.js +26 -0
- package/dist/nexum-analysis/knowledge-read.js.map +1 -0
- package/dist/openapi/openapi.json +18354 -17718
- package/dist/patches/access.d.ts +15 -0
- package/dist/patches/access.d.ts.map +1 -0
- package/dist/patches/access.js +27 -0
- package/dist/patches/access.js.map +1 -0
- package/dist/patches/engine.d.ts +67 -0
- package/dist/patches/engine.d.ts.map +1 -0
- package/dist/patches/engine.js +966 -0
- package/dist/patches/engine.js.map +1 -0
- package/dist/patches/guards.d.ts +23 -0
- package/dist/patches/guards.d.ts.map +1 -0
- package/dist/patches/guards.js +77 -0
- package/dist/patches/guards.js.map +1 -0
- package/dist/patches/legacy-rows.d.ts +56 -0
- package/dist/patches/legacy-rows.d.ts.map +1 -0
- package/dist/patches/legacy-rows.js +162 -0
- package/dist/patches/legacy-rows.js.map +1 -0
- package/dist/patches/ops.d.ts +24 -0
- package/dist/patches/ops.d.ts.map +1 -0
- package/dist/patches/ops.js +204 -0
- package/dist/patches/ops.js.map +1 -0
- package/dist/patches/parse.d.ts +5 -0
- package/dist/patches/parse.d.ts.map +1 -0
- package/dist/patches/parse.js +323 -0
- package/dist/patches/parse.js.map +1 -0
- package/dist/patches/paths.d.ts +38 -0
- package/dist/patches/paths.d.ts.map +1 -0
- package/dist/patches/paths.js +204 -0
- package/dist/patches/paths.js.map +1 -0
- package/dist/patches/service.d.ts +16 -0
- package/dist/patches/service.d.ts.map +1 -0
- package/dist/patches/service.js +128 -0
- package/dist/patches/service.js.map +1 -0
- package/dist/patches/store.d.ts +87 -0
- package/dist/patches/store.d.ts.map +1 -0
- package/dist/patches/store.js +27 -0
- package/dist/patches/store.js.map +1 -0
- package/dist/patches/types.d.ts +112 -0
- package/dist/patches/types.d.ts.map +1 -0
- package/dist/patches/types.js +5 -0
- package/dist/patches/types.js.map +1 -0
- package/dist/platform.d.ts +8 -0
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +98 -4
- package/dist/platform.js.map +1 -1
- package/dist/routes/anomaly.d.ts +5 -0
- package/dist/routes/anomaly.d.ts.map +1 -0
- package/dist/routes/anomaly.js +308 -0
- package/dist/routes/anomaly.js.map +1 -0
- package/dist/routes/data.d.ts.map +1 -1
- package/dist/routes/data.js +190 -202
- package/dist/routes/data.js.map +1 -1
- package/dist/routes/knowledge.d.ts.map +1 -1
- package/dist/routes/knowledge.js +6 -22
- package/dist/routes/knowledge.js.map +1 -1
- package/dist/routes/metadata.d.ts.map +1 -1
- package/dist/routes/metadata.js +28 -1
- package/dist/routes/metadata.js.map +1 -1
- package/dist/routes/patches.d.ts +7 -0
- package/dist/routes/patches.d.ts.map +1 -0
- package/dist/routes/patches.js +111 -0
- package/dist/routes/patches.js.map +1 -0
- package/dist/routes/subject-roots-backfill.d.ts +4 -0
- package/dist/routes/subject-roots-backfill.d.ts.map +1 -0
- package/dist/routes/subject-roots-backfill.js +15 -0
- package/dist/routes/subject-roots-backfill.js.map +1 -0
- package/dist/single-read-discriminator.d.ts +17 -0
- package/dist/single-read-discriminator.d.ts.map +1 -0
- package/dist/single-read-discriminator.js +67 -0
- package/dist/single-read-discriminator.js.map +1 -0
- package/dist/subject-roots-backfill.d.ts +24 -0
- package/dist/subject-roots-backfill.d.ts.map +1 -0
- package/dist/subject-roots-backfill.js +133 -0
- package/dist/subject-roots-backfill.js.map +1 -0
- package/dist/write-precondition.d.ts +5 -1
- package/dist/write-precondition.d.ts.map +1 -1
- package/dist/write-precondition.js +11 -3
- package/dist/write-precondition.js.map +1 -1
- package/dist/writes/content-write.d.ts +170 -0
- package/dist/writes/content-write.d.ts.map +1 -0
- package/dist/writes/content-write.js +569 -0
- package/dist/writes/content-write.js.map +1 -0
- package/dist/writes/effects.d.ts +13 -0
- package/dist/writes/effects.d.ts.map +1 -0
- package/dist/writes/effects.js +28 -0
- package/dist/writes/effects.js.map +1 -0
- package/dist/writes/error-shape.d.ts +11 -0
- package/dist/writes/error-shape.d.ts.map +1 -0
- package/dist/writes/error-shape.js +100 -0
- package/dist/writes/error-shape.js.map +1 -0
- package/dist/writes/receipt-store.d.ts +81 -0
- package/dist/writes/receipt-store.d.ts.map +1 -0
- package/dist/writes/receipt-store.js +171 -0
- package/dist/writes/receipt-store.js.map +1 -0
- package/dist/writes/worker.d.ts +9 -0
- package/dist/writes/worker.d.ts.map +1 -0
- package/dist/writes/worker.js +20 -0
- package/dist/writes/worker.js.map +1 -0
- package/openapi/openapi.json +18354 -17718
- package/package.json +4 -4
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Record paths for patches. `.` separates keys. A key ending in `[]` steps into each array member.
|
|
3
|
+
*/
|
|
4
|
+
import { isDeepStrictEqual } from "node:util";
|
|
5
|
+
const BLOCKED_KEYS = new Set(["__proto__", "prototype", "constructor"]);
|
|
6
|
+
/** A row cannot take this op as written, for example a path through a string. */
|
|
7
|
+
export class PatchRowError extends Error {
|
|
8
|
+
constructor(message) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.name = "PatchRowError";
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export function isPlainObject(value) {
|
|
14
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
15
|
+
}
|
|
16
|
+
function has(node, key) {
|
|
17
|
+
return Object.prototype.hasOwnProperty.call(node, key);
|
|
18
|
+
}
|
|
19
|
+
export function parsePath(path) {
|
|
20
|
+
const parts = path.split(".");
|
|
21
|
+
return parts.map((part) => {
|
|
22
|
+
const each = part.endsWith("[]");
|
|
23
|
+
const key = each ? part.slice(0, -2) : part;
|
|
24
|
+
if (!key)
|
|
25
|
+
throw new Error(`empty key in ${JSON.stringify(path)}`);
|
|
26
|
+
if (key.includes("[") || key.includes("]"))
|
|
27
|
+
throw new Error(`bad array step in ${JSON.stringify(path)}`);
|
|
28
|
+
if (BLOCKED_KEYS.has(key))
|
|
29
|
+
throw new Error(`key ${key} is not allowed`);
|
|
30
|
+
return { key, each };
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
/** Every place the path names. The last key may be absent at a location. */
|
|
34
|
+
export function locate(root, segments) {
|
|
35
|
+
let frontier = [root];
|
|
36
|
+
const out = [];
|
|
37
|
+
segments.forEach((segment, index) => {
|
|
38
|
+
const last = index === segments.length - 1;
|
|
39
|
+
const next = [];
|
|
40
|
+
for (const node of frontier) {
|
|
41
|
+
if (!isPlainObject(node))
|
|
42
|
+
continue;
|
|
43
|
+
if (!segment.each) {
|
|
44
|
+
if (last)
|
|
45
|
+
out.push({ parent: node, key: segment.key });
|
|
46
|
+
else if (has(node, segment.key))
|
|
47
|
+
next.push(node[segment.key]);
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
const list = has(node, segment.key) ? node[segment.key] : undefined;
|
|
51
|
+
if (!Array.isArray(list))
|
|
52
|
+
continue;
|
|
53
|
+
if (last)
|
|
54
|
+
list.forEach((_, i) => out.push({ parent: list, key: i }));
|
|
55
|
+
else
|
|
56
|
+
next.push(...list);
|
|
57
|
+
}
|
|
58
|
+
frontier = next;
|
|
59
|
+
});
|
|
60
|
+
return out;
|
|
61
|
+
}
|
|
62
|
+
export function isPresent(location) {
|
|
63
|
+
if (Array.isArray(location.parent))
|
|
64
|
+
return typeof location.key === "number" && location.key < location.parent.length;
|
|
65
|
+
return has(location.parent, String(location.key));
|
|
66
|
+
}
|
|
67
|
+
export function valueAt(location) {
|
|
68
|
+
return Array.isArray(location.parent)
|
|
69
|
+
? location.parent[location.key]
|
|
70
|
+
: location.parent[String(location.key)];
|
|
71
|
+
}
|
|
72
|
+
export function writeAt(location, value) {
|
|
73
|
+
if (Array.isArray(location.parent))
|
|
74
|
+
location.parent[location.key] = value;
|
|
75
|
+
else
|
|
76
|
+
location.parent[String(location.key)] = value;
|
|
77
|
+
}
|
|
78
|
+
export function readValues(root, path) {
|
|
79
|
+
return locate(root, parsePath(path)).filter(isPresent).map(valueAt);
|
|
80
|
+
}
|
|
81
|
+
/** Value at a path without array steps, or undefined. */
|
|
82
|
+
export function readPlain(root, path) {
|
|
83
|
+
let cur = root;
|
|
84
|
+
for (const segment of parsePath(path)) {
|
|
85
|
+
if (!isPlainObject(cur) || !has(cur, segment.key))
|
|
86
|
+
return undefined;
|
|
87
|
+
cur = cur[segment.key];
|
|
88
|
+
}
|
|
89
|
+
return cur;
|
|
90
|
+
}
|
|
91
|
+
export function hasPlain(root, path) {
|
|
92
|
+
const segments = parsePath(path);
|
|
93
|
+
let cur = root;
|
|
94
|
+
for (const segment of segments) {
|
|
95
|
+
if (!isPlainObject(cur) || !has(cur, segment.key))
|
|
96
|
+
return false;
|
|
97
|
+
cur = cur[segment.key];
|
|
98
|
+
}
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
/** Set a value, creating objects on the way. A non-object on the way fails the row. */
|
|
102
|
+
export function setPlain(root, path, value) {
|
|
103
|
+
const segments = parsePath(path);
|
|
104
|
+
let cur = root;
|
|
105
|
+
for (let i = 0; i < segments.length - 1; i += 1) {
|
|
106
|
+
const key = segments[i].key;
|
|
107
|
+
if (!has(cur, key) || cur[key] === undefined || cur[key] === null)
|
|
108
|
+
cur[key] = {};
|
|
109
|
+
const child = cur[key];
|
|
110
|
+
if (!isPlainObject(child)) {
|
|
111
|
+
throw new PatchRowError(`${segments.slice(0, i + 1).map((s) => s.key).join(".")} is not an object`);
|
|
112
|
+
}
|
|
113
|
+
cur = child;
|
|
114
|
+
}
|
|
115
|
+
cur[segments.at(-1).key] = value;
|
|
116
|
+
}
|
|
117
|
+
export function deletePlain(root, path) {
|
|
118
|
+
const segments = parsePath(path);
|
|
119
|
+
let cur = root;
|
|
120
|
+
for (let i = 0; i < segments.length - 1; i += 1) {
|
|
121
|
+
if (!isPlainObject(cur) || !has(cur, segments[i].key))
|
|
122
|
+
return false;
|
|
123
|
+
cur = cur[segments[i].key];
|
|
124
|
+
}
|
|
125
|
+
const key = segments.at(-1).key;
|
|
126
|
+
if (!isPlainObject(cur) || !has(cur, key))
|
|
127
|
+
return false;
|
|
128
|
+
delete cur[key];
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
/** Values of `key` at any depth under `value`, including inside arrays. */
|
|
132
|
+
export function valuesForKey(value, key, out = []) {
|
|
133
|
+
if (Array.isArray(value)) {
|
|
134
|
+
for (const item of value)
|
|
135
|
+
valuesForKey(item, key, out);
|
|
136
|
+
return out;
|
|
137
|
+
}
|
|
138
|
+
if (!isPlainObject(value))
|
|
139
|
+
return out;
|
|
140
|
+
for (const [childKey, child] of Object.entries(value)) {
|
|
141
|
+
if (childKey === key)
|
|
142
|
+
out.push(child);
|
|
143
|
+
valuesForKey(child, key, out);
|
|
144
|
+
}
|
|
145
|
+
return out;
|
|
146
|
+
}
|
|
147
|
+
/** Remove `key` at every depth under `value`. With `when`, only where its value passes. */
|
|
148
|
+
export function deleteKeyEverywhere(value, key, when) {
|
|
149
|
+
let changed = false;
|
|
150
|
+
if (Array.isArray(value)) {
|
|
151
|
+
for (const item of value)
|
|
152
|
+
changed = deleteKeyEverywhere(item, key, when) || changed;
|
|
153
|
+
return changed;
|
|
154
|
+
}
|
|
155
|
+
if (!isPlainObject(value))
|
|
156
|
+
return false;
|
|
157
|
+
if (has(value, key) && (!when || testValues([value[key]], when))) {
|
|
158
|
+
delete value[key];
|
|
159
|
+
changed = true;
|
|
160
|
+
}
|
|
161
|
+
for (const child of Object.values(value))
|
|
162
|
+
changed = deleteKeyEverywhere(child, key, when) || changed;
|
|
163
|
+
return changed;
|
|
164
|
+
}
|
|
165
|
+
const regexCache = new Map();
|
|
166
|
+
function regex(pattern) {
|
|
167
|
+
let compiled = regexCache.get(pattern);
|
|
168
|
+
if (!compiled) {
|
|
169
|
+
compiled = new RegExp(pattern);
|
|
170
|
+
if (regexCache.size > 500)
|
|
171
|
+
regexCache.clear();
|
|
172
|
+
regexCache.set(pattern, compiled);
|
|
173
|
+
}
|
|
174
|
+
return compiled;
|
|
175
|
+
}
|
|
176
|
+
export function matchesPattern(value, pattern) {
|
|
177
|
+
return typeof value === "string" && regex(pattern).test(value);
|
|
178
|
+
}
|
|
179
|
+
/** `values` are what the path or key found. Absent locations are not in the list. */
|
|
180
|
+
export function testValues(values, test) {
|
|
181
|
+
if (test.exists)
|
|
182
|
+
return values.length > 0;
|
|
183
|
+
if (test.missing)
|
|
184
|
+
return values.length === 0;
|
|
185
|
+
if (Object.prototype.hasOwnProperty.call(test, "equals")) {
|
|
186
|
+
return values.some((value) => isDeepStrictEqual(value, test.equals));
|
|
187
|
+
}
|
|
188
|
+
if (test.in) {
|
|
189
|
+
const candidates = test.in;
|
|
190
|
+
return values.some((value) => candidates.some((candidate) => isDeepStrictEqual(value, candidate)));
|
|
191
|
+
}
|
|
192
|
+
if (test.matches !== undefined) {
|
|
193
|
+
const pattern = test.matches;
|
|
194
|
+
return values.some((value) => matchesPattern(value, pattern));
|
|
195
|
+
}
|
|
196
|
+
return values.length > 0;
|
|
197
|
+
}
|
|
198
|
+
export function evaluatePredicate(record, predicate) {
|
|
199
|
+
const values = "key" in predicate
|
|
200
|
+
? valuesForKey(record.data, predicate.key)
|
|
201
|
+
: readValues(record, predicate.path);
|
|
202
|
+
return testValues(values, predicate);
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/patches/paths.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MX-PATCH-01 — platform wiring for the patch engine: deps per request, guard checks on content writes,
|
|
3
|
+
* and the ticker that resumes apply and revert work after a restart.
|
|
4
|
+
*/
|
|
5
|
+
import type { MemorixPlatform } from "../platform.js";
|
|
6
|
+
import type { MemorixScope } from "../scope.js";
|
|
7
|
+
import type { StoredContentWrite } from "../writes/receipt-store.js";
|
|
8
|
+
import { type PatchEngineDeps } from "./engine.js";
|
|
9
|
+
export declare function patchEngineDeps(platform: MemorixPlatform, scope: MemorixScope, caller: string): PatchEngineDeps;
|
|
10
|
+
/** `checkWrite` for content writes: 400 `PATCH_GUARD` when the write matches an installed guard. */
|
|
11
|
+
export declare function patchGuardCheck(platform: MemorixPlatform, scope: MemorixScope): (request: StoredContentWrite) => Promise<void>;
|
|
12
|
+
/** Resume apply or revert work whose lease ran out (another instance died, or this one restarted). */
|
|
13
|
+
export declare function startPatchTicker(platform: MemorixPlatform, opts?: {
|
|
14
|
+
intervalMs?: number;
|
|
15
|
+
}): () => void;
|
|
16
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/patches/service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAKhD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAIpE,wBAAgB,eAAe,CAAC,QAAQ,EAAE,eAAe,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,eAAe,CA0C/G;AAED,oGAAoG;AACpG,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,eAAe,EACzB,KAAK,EAAE,YAAY,GAClB,CAAC,OAAO,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,CAAC,CAoBhD;AAED,sGAAsG;AACtG,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,eAAe,EAAE,IAAI,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,IAAI,CA0CtG"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { ServiceError } from "../errors.js";
|
|
2
|
+
import { declaredDiscriminatorValues } from "../catalog-bridge.js";
|
|
3
|
+
import { maybeEnqueueNexumAnalysis } from "../nexum-analysis/enqueue.js";
|
|
4
|
+
import { isOperationalDbName, orgIdFromOperationalDbName } from "../operational-db.js";
|
|
5
|
+
import { resumePatchWork } from "./engine.js";
|
|
6
|
+
import { assertPatchGuards } from "./guards.js";
|
|
7
|
+
import { PATCHES_COLLECTION } from "./store.js";
|
|
8
|
+
export function patchEngineDeps(platform, scope, caller) {
|
|
9
|
+
const client = platform.getMongoClient();
|
|
10
|
+
if (!client) {
|
|
11
|
+
throw new ServiceError("PATCH_UNAVAILABLE", "patches need the MongoDB data plane", 503, { retryable: false });
|
|
12
|
+
}
|
|
13
|
+
const resolved = { ...scope, orgId: platform.resolveOrgId(scope.orgId) };
|
|
14
|
+
const ports = platform.portsFor(resolved);
|
|
15
|
+
return {
|
|
16
|
+
client,
|
|
17
|
+
operationalDb: platform.operationalDbFor(resolved.orgId),
|
|
18
|
+
scope: { orgId: resolved.orgId, agentIds: [...resolved.agentIds] },
|
|
19
|
+
catalog: ports.catalog,
|
|
20
|
+
caller,
|
|
21
|
+
reconcileDirectory: async (recordId) => {
|
|
22
|
+
await ports.writer.reconcileDirectory(resolved, recordId);
|
|
23
|
+
},
|
|
24
|
+
onRowWritten: async (event) => {
|
|
25
|
+
try {
|
|
26
|
+
platform.analytics?.onWrite(resolved, {
|
|
27
|
+
objectType: event.objectType,
|
|
28
|
+
contentType: event.contentType,
|
|
29
|
+
recordId: event.recordId,
|
|
30
|
+
op: event.op,
|
|
31
|
+
datasourceService: caller,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
/* tracking never fails a patch */
|
|
36
|
+
}
|
|
37
|
+
if (event.op === "removed" || event.revision === undefined)
|
|
38
|
+
return;
|
|
39
|
+
await maybeEnqueueNexumAnalysis({
|
|
40
|
+
platform,
|
|
41
|
+
scope: resolved,
|
|
42
|
+
objectType: event.objectType,
|
|
43
|
+
contentType: event.contentType,
|
|
44
|
+
recordId: event.recordId,
|
|
45
|
+
revision: event.revision,
|
|
46
|
+
data: event.data,
|
|
47
|
+
}).catch(() => undefined);
|
|
48
|
+
},
|
|
49
|
+
declaredDiscriminatorValues: (objectType, contentType, path) => declaredDiscriminatorValues(platform.metadata, resolved.agentIds, objectType, contentType, path),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/** `checkWrite` for content writes: 400 `PATCH_GUARD` when the write matches an installed guard. */
|
|
53
|
+
export function patchGuardCheck(platform, scope) {
|
|
54
|
+
return async (request) => {
|
|
55
|
+
if (!platform.getMongoClient())
|
|
56
|
+
return;
|
|
57
|
+
const orgId = platform.resolveOrgId(scope.orgId);
|
|
58
|
+
const recordId = typeof request.record?.recordId === "string" ? request.record.recordId : undefined;
|
|
59
|
+
await assertPatchGuards({
|
|
60
|
+
db: platform.operationalDbFor(orgId),
|
|
61
|
+
orgId,
|
|
62
|
+
write: request,
|
|
63
|
+
readCurrent: recordId
|
|
64
|
+
? async () => (await platform.portsFor(scope).reader.getContent(scope, {
|
|
65
|
+
objectType: request.objectType,
|
|
66
|
+
contentType: request.contentType,
|
|
67
|
+
recordId,
|
|
68
|
+
...(request.discriminatorValue ? { discriminatorValue: request.discriminatorValue } : {}),
|
|
69
|
+
}))
|
|
70
|
+
: undefined,
|
|
71
|
+
});
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/** Resume apply or revert work whose lease ran out (another instance died, or this one restarted). */
|
|
75
|
+
export function startPatchTicker(platform, opts) {
|
|
76
|
+
const intervalMs = opts?.intervalMs ?? 5_000;
|
|
77
|
+
let busy = false;
|
|
78
|
+
const tickOnce = async () => {
|
|
79
|
+
if (busy)
|
|
80
|
+
return;
|
|
81
|
+
busy = true;
|
|
82
|
+
try {
|
|
83
|
+
const client = platform.getMongoClient();
|
|
84
|
+
if (!client)
|
|
85
|
+
return;
|
|
86
|
+
const dbs = await client.db().admin().listDatabases({ nameOnly: true });
|
|
87
|
+
for (const d of dbs.databases ?? []) {
|
|
88
|
+
const name = d.name ?? "";
|
|
89
|
+
if (!isOperationalDbName(name))
|
|
90
|
+
continue;
|
|
91
|
+
const orgId = orgIdFromOperationalDbName(name);
|
|
92
|
+
if (!orgId)
|
|
93
|
+
continue;
|
|
94
|
+
try {
|
|
95
|
+
const db = platform.operationalDbFor(orgId);
|
|
96
|
+
const busyPatches = await db
|
|
97
|
+
.collection(PATCHES_COLLECTION)
|
|
98
|
+
.countDocuments({ state: { $in: ["applying", "reverting"] } }, { limit: 1 });
|
|
99
|
+
if (!busyPatches)
|
|
100
|
+
continue;
|
|
101
|
+
await resumePatchWork(db, (patch) => {
|
|
102
|
+
try {
|
|
103
|
+
return patchEngineDeps(platform, { orgId: patch.orgId, agentIds: patch.agentIds }, patch.caller);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// One org must not stop the others.
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
// Ticker must not crash the service.
|
|
117
|
+
}
|
|
118
|
+
finally {
|
|
119
|
+
busy = false;
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
void tickOnce();
|
|
123
|
+
const handle = setInterval(() => void tickOnce(), intervalMs);
|
|
124
|
+
if (typeof handle.unref === "function")
|
|
125
|
+
handle.unref();
|
|
126
|
+
return () => clearInterval(handle);
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/patches/service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { Collection, Db } from "mongodb";
|
|
2
|
+
import type { PatchCounts, PatchGuard, PatchRequest, PatchSample, PatchState, RevertCounts, RevertOutcome, RowOutcome } from "./types.js";
|
|
3
|
+
export declare const PATCHES_COLLECTION = "memorix_patches";
|
|
4
|
+
export declare const PATCH_ROWS_COLLECTION = "memorix_patch_rows";
|
|
5
|
+
export type PlannedOutcome = "change" | "unchanged" | "conflict" | "fail";
|
|
6
|
+
/** A stored content document: `_id` is the storage key. */
|
|
7
|
+
export type StoredDoc = {
|
|
8
|
+
_id: string;
|
|
9
|
+
[key: string]: unknown;
|
|
10
|
+
};
|
|
11
|
+
export type PatchDoc = {
|
|
12
|
+
_id: string;
|
|
13
|
+
patchId: string;
|
|
14
|
+
orgId: string;
|
|
15
|
+
agentIds: string[];
|
|
16
|
+
caller: string;
|
|
17
|
+
objectType: string;
|
|
18
|
+
contentTypes: string[];
|
|
19
|
+
request: PatchRequest;
|
|
20
|
+
state: PatchState;
|
|
21
|
+
planChecksum: string;
|
|
22
|
+
plan: {
|
|
23
|
+
matched: number;
|
|
24
|
+
wouldChange: number;
|
|
25
|
+
unchanged: number;
|
|
26
|
+
conflicts: number;
|
|
27
|
+
failed: number;
|
|
28
|
+
limitHit: boolean;
|
|
29
|
+
warnings: string[];
|
|
30
|
+
samples: PatchSample[];
|
|
31
|
+
};
|
|
32
|
+
counts: PatchCounts;
|
|
33
|
+
revertCounts?: RevertCounts;
|
|
34
|
+
guards: PatchGuard[];
|
|
35
|
+
guardsActive: boolean;
|
|
36
|
+
createdAt: string;
|
|
37
|
+
planExpiresAt: string;
|
|
38
|
+
startedAt?: string;
|
|
39
|
+
finishedAt?: string;
|
|
40
|
+
revertRetainUntil?: string;
|
|
41
|
+
revertStartedAt?: string;
|
|
42
|
+
revertedAt?: string;
|
|
43
|
+
appliedBy?: string;
|
|
44
|
+
revertedBy?: string;
|
|
45
|
+
error?: string;
|
|
46
|
+
lease?: {
|
|
47
|
+
owner: string;
|
|
48
|
+
until: string;
|
|
49
|
+
};
|
|
50
|
+
/** TTL: set while the plan waits for apply. */
|
|
51
|
+
expireAt?: Date;
|
|
52
|
+
};
|
|
53
|
+
export type PatchRowDoc = {
|
|
54
|
+
_id: string;
|
|
55
|
+
patchId: string;
|
|
56
|
+
seq: number;
|
|
57
|
+
objectType: string;
|
|
58
|
+
contentType: string;
|
|
59
|
+
recordId: string;
|
|
60
|
+
storageKey: string;
|
|
61
|
+
plannedRevision: number;
|
|
62
|
+
planned: PlannedOutcome;
|
|
63
|
+
plannedError?: string;
|
|
64
|
+
outcome?: RowOutcome;
|
|
65
|
+
error?: string;
|
|
66
|
+
/** The stored document before the patch wrote it. Kept for revert. */
|
|
67
|
+
before?: StoredDoc;
|
|
68
|
+
/** The instance a `setDiscriminator` with `onExisting: "replace"` overwrote. */
|
|
69
|
+
beforeTarget?: StoredDoc;
|
|
70
|
+
after?: {
|
|
71
|
+
storageKey: string;
|
|
72
|
+
revision: number;
|
|
73
|
+
} | {
|
|
74
|
+
deleted: true;
|
|
75
|
+
keptStorageKey?: string;
|
|
76
|
+
mode: "purge" | "legacy";
|
|
77
|
+
};
|
|
78
|
+
revert?: RevertOutcome;
|
|
79
|
+
revertError?: string;
|
|
80
|
+
expireAt: Date;
|
|
81
|
+
};
|
|
82
|
+
export type PatchCollections = {
|
|
83
|
+
patches: Collection<PatchDoc>;
|
|
84
|
+
rows: Collection<PatchRowDoc>;
|
|
85
|
+
};
|
|
86
|
+
export declare function patchCollections(db: Db): Promise<PatchCollections>;
|
|
87
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/patches/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export const PATCHES_COLLECTION = "memorix_patches";
|
|
2
|
+
export const PATCH_ROWS_COLLECTION = "memorix_patch_rows";
|
|
3
|
+
const indexed = new Set();
|
|
4
|
+
export async function patchCollections(db) {
|
|
5
|
+
const patches = db.collection(PATCHES_COLLECTION);
|
|
6
|
+
const rows = db.collection(PATCH_ROWS_COLLECTION);
|
|
7
|
+
if (!indexed.has(db.databaseName)) {
|
|
8
|
+
indexed.add(db.databaseName);
|
|
9
|
+
try {
|
|
10
|
+
await Promise.all([
|
|
11
|
+
patches.createIndex({ expireAt: 1 }, { name: "plan_ttl", expireAfterSeconds: 0 }),
|
|
12
|
+
patches.createIndex({ objectType: 1, createdAt: -1 }, { name: "object_type_created" }),
|
|
13
|
+
patches.createIndex({ state: 1 }, { name: "state" }),
|
|
14
|
+
patches.createIndex({ guardsActive: 1 }, { name: "guards_active" }),
|
|
15
|
+
rows.createIndex({ patchId: 1, seq: 1 }, { name: "patch_seq", unique: true }),
|
|
16
|
+
rows.createIndex({ patchId: 1, outcome: 1, seq: 1 }, { name: "patch_outcome_seq" }),
|
|
17
|
+
rows.createIndex({ expireAt: 1 }, { name: "row_ttl", expireAfterSeconds: 0 }),
|
|
18
|
+
]);
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
indexed.delete(db.databaseName);
|
|
22
|
+
throw err;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return { patches, rows };
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/patches/store.ts"],"names":[],"mappings":"AAYA,MAAM,CAAC,MAAM,kBAAkB,GAAG,iBAAiB,CAAC;AACpD,MAAM,CAAC,MAAM,qBAAqB,GAAG,oBAAoB,CAAC;AA2E1D,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;AAElC,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,EAAM;IAC3C,MAAM,OAAO,GAAG,EAAE,CAAC,UAAU,CAAW,kBAAkB,CAAC,CAAC;IAC5D,MAAM,IAAI,GAAG,EAAE,CAAC,UAAU,CAAc,qBAAqB,CAAC,CAAC;IAC/D,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,GAAG,CAAC;gBAChB,OAAO,CAAC,WAAW,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,kBAAkB,EAAE,CAAC,EAAE,CAAC;gBACjF,OAAO,CAAC,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE,CAAC;gBACtF,OAAO,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;gBACpD,OAAO,CAAC,WAAW,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC;gBACnE,IAAI,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;gBAC7E,IAAI,CAAC,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC;gBACnF,IAAI,CAAC,WAAW,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAAC,EAAE,CAAC;aAC9E,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC;YAChC,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC3B,CAAC"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MX-PATCH-01 — a patch request repairs stored rows: `select`, ordered `ops`, optional `guards`.
|
|
3
|
+
*/
|
|
4
|
+
export type ValueTest = {
|
|
5
|
+
exists?: true;
|
|
6
|
+
missing?: true;
|
|
7
|
+
equals?: unknown;
|
|
8
|
+
in?: unknown[];
|
|
9
|
+
matches?: string;
|
|
10
|
+
};
|
|
11
|
+
/** A predicate on a record path, or on a key at any depth under `data`. */
|
|
12
|
+
export type Predicate = ({
|
|
13
|
+
path: string;
|
|
14
|
+
} & ValueTest) | ({
|
|
15
|
+
key: string;
|
|
16
|
+
anyDepth: true;
|
|
17
|
+
} & ValueTest);
|
|
18
|
+
export type PatchSelect = {
|
|
19
|
+
objectType: string;
|
|
20
|
+
contentTypes: string[];
|
|
21
|
+
recordIds?: string[];
|
|
22
|
+
idPrefix?: string;
|
|
23
|
+
discriminator?: {
|
|
24
|
+
value: string;
|
|
25
|
+
} | {
|
|
26
|
+
absent: true;
|
|
27
|
+
};
|
|
28
|
+
where?: Predicate[];
|
|
29
|
+
state: "active" | "tombstoned" | "any";
|
|
30
|
+
limit?: number;
|
|
31
|
+
};
|
|
32
|
+
export type PatchOp = {
|
|
33
|
+
op: "set";
|
|
34
|
+
path: string;
|
|
35
|
+
value: unknown;
|
|
36
|
+
onlyIfAbsent?: boolean;
|
|
37
|
+
} | {
|
|
38
|
+
op: "delete";
|
|
39
|
+
path: string;
|
|
40
|
+
when?: ValueTest;
|
|
41
|
+
} | {
|
|
42
|
+
op: "delete";
|
|
43
|
+
key: string;
|
|
44
|
+
anyDepth: true;
|
|
45
|
+
when?: ValueTest;
|
|
46
|
+
} | {
|
|
47
|
+
op: "move";
|
|
48
|
+
from: string;
|
|
49
|
+
to: string;
|
|
50
|
+
overwrite?: boolean;
|
|
51
|
+
} | {
|
|
52
|
+
op: "copy";
|
|
53
|
+
from: string;
|
|
54
|
+
to: string;
|
|
55
|
+
overwrite?: boolean;
|
|
56
|
+
} | {
|
|
57
|
+
op: "rename";
|
|
58
|
+
path: string;
|
|
59
|
+
to: string;
|
|
60
|
+
} | {
|
|
61
|
+
op: "mapValues";
|
|
62
|
+
path: string;
|
|
63
|
+
map: Record<string, unknown>;
|
|
64
|
+
} | {
|
|
65
|
+
op: "dropValues";
|
|
66
|
+
path: string;
|
|
67
|
+
values?: string[];
|
|
68
|
+
matches?: string;
|
|
69
|
+
} | {
|
|
70
|
+
op: "prune";
|
|
71
|
+
path?: string;
|
|
72
|
+
} | {
|
|
73
|
+
op: "setDiscriminator";
|
|
74
|
+
value: string;
|
|
75
|
+
onExisting?: "skip" | "replace" | "deleteLegacy";
|
|
76
|
+
} | {
|
|
77
|
+
op: "deleteRecord";
|
|
78
|
+
mode?: "tombstone" | "purge";
|
|
79
|
+
};
|
|
80
|
+
export type PatchGuard = {
|
|
81
|
+
rejectWhen: Predicate;
|
|
82
|
+
message: string;
|
|
83
|
+
};
|
|
84
|
+
export type PatchRequest = {
|
|
85
|
+
reason?: string;
|
|
86
|
+
select: PatchSelect;
|
|
87
|
+
ops: PatchOp[];
|
|
88
|
+
guards: PatchGuard[];
|
|
89
|
+
};
|
|
90
|
+
export type PatchState = "planned" | "applying" | "applied" | "failed" | "reverting" | "reverted";
|
|
91
|
+
export type RowOutcome = "changed" | "unchanged" | "drifted" | "conflict" | "failed";
|
|
92
|
+
export type RevertOutcome = "reverted" | "drifted" | "failed" | "skipped";
|
|
93
|
+
export type PatchCounts = {
|
|
94
|
+
changed: number;
|
|
95
|
+
unchanged: number;
|
|
96
|
+
drifted: number;
|
|
97
|
+
conflicts: number;
|
|
98
|
+
failed: number;
|
|
99
|
+
};
|
|
100
|
+
export type RevertCounts = {
|
|
101
|
+
reverted: number;
|
|
102
|
+
drifted: number;
|
|
103
|
+
failed: number;
|
|
104
|
+
};
|
|
105
|
+
export type PatchSample = {
|
|
106
|
+
recordId: string;
|
|
107
|
+
contentType: string;
|
|
108
|
+
revision: number;
|
|
109
|
+
before: Record<string, unknown>;
|
|
110
|
+
after: Record<string, unknown>;
|
|
111
|
+
};
|
|
112
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/patches/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/patches/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
package/dist/platform.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ import { ServiceError } from "./errors.js";
|
|
|
15
15
|
import { type DeliveryArtifactStore, type RawRecordStore, type TargetItemReceiptStore } from "./mgc-landing-stores.js";
|
|
16
16
|
import { type ServiceCatalog } from "./catalog-bridge.js";
|
|
17
17
|
import { type MemorixScope } from "./scope.js";
|
|
18
|
+
import { type WriteReceiptStore } from "./writes/receipt-store.js";
|
|
18
19
|
import type { HookStore } from "./hooks/types.js";
|
|
19
20
|
import { type IsolationSession } from "./isolation.js";
|
|
20
21
|
import { type MagitPackService } from "./magit/magit-pack-service.js";
|
|
@@ -188,6 +189,13 @@ export type MemorixPlatform = {
|
|
|
188
189
|
}): () => void;
|
|
189
190
|
/** Content-hook subscriptions and deliveries for one org. */
|
|
190
191
|
hooksFor(orgId: string): HookStore;
|
|
192
|
+
/** Accepted content writes for one org. */
|
|
193
|
+
writeReceiptsFor(orgId: string): WriteReceiptStore;
|
|
194
|
+
/** Retry content writes that were accepted and not finished. */
|
|
195
|
+
startWriteReceiptTicker(opts?: {
|
|
196
|
+
intervalMs?: number;
|
|
197
|
+
}): () => void;
|
|
198
|
+
tickWriteReceipts(): Promise<void>;
|
|
191
199
|
/** Deliver pending content hooks. Works with memory stores when Mongo is absent. */
|
|
192
200
|
startContentHookTicker(opts?: {
|
|
193
201
|
intervalMs?: number;
|