@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.
Files changed (151) hide show
  1. package/README.md +1 -1
  2. package/dist/anomaly/catalog.d.ts +4 -0
  3. package/dist/anomaly/catalog.d.ts.map +1 -0
  4. package/dist/anomaly/catalog.js +315 -0
  5. package/dist/anomaly/catalog.js.map +1 -0
  6. package/dist/anomaly/descriptors.d.ts +11 -0
  7. package/dist/anomaly/descriptors.d.ts.map +1 -0
  8. package/dist/anomaly/descriptors.js +113 -0
  9. package/dist/anomaly/descriptors.js.map +1 -0
  10. package/dist/anomaly/index.d.ts +6 -0
  11. package/dist/anomaly/index.d.ts.map +1 -0
  12. package/dist/anomaly/index.js +5 -0
  13. package/dist/anomaly/index.js.map +1 -0
  14. package/dist/anomaly/records.d.ts +28 -0
  15. package/dist/anomaly/records.d.ts.map +1 -0
  16. package/dist/anomaly/records.js +384 -0
  17. package/dist/anomaly/records.js.map +1 -0
  18. package/dist/anomaly/types.d.ts +116 -0
  19. package/dist/anomaly/types.d.ts.map +1 -0
  20. package/dist/anomaly/types.js +24 -0
  21. package/dist/anomaly/types.js.map +1 -0
  22. package/dist/anomaly/values.d.ts +31 -0
  23. package/dist/anomaly/values.d.ts.map +1 -0
  24. package/dist/anomaly/values.js +171 -0
  25. package/dist/anomaly/values.js.map +1 -0
  26. package/dist/app.d.ts.map +1 -1
  27. package/dist/app.js +12 -0
  28. package/dist/app.js.map +1 -1
  29. package/dist/catalog-bridge.d.ts +18 -0
  30. package/dist/catalog-bridge.d.ts.map +1 -1
  31. package/dist/catalog-bridge.js +85 -0
  32. package/dist/catalog-bridge.js.map +1 -1
  33. package/dist/errors.d.ts +5 -0
  34. package/dist/errors.d.ts.map +1 -1
  35. package/dist/errors.js +18 -0
  36. package/dist/errors.js.map +1 -1
  37. package/dist/knowledge-upstream.d.ts +32 -0
  38. package/dist/knowledge-upstream.d.ts.map +1 -1
  39. package/dist/knowledge-upstream.js +86 -2
  40. package/dist/knowledge-upstream.js.map +1 -1
  41. package/dist/mcp/nexum-tools.d.ts +1 -1
  42. package/dist/mcp/nexum-tools.d.ts.map +1 -1
  43. package/dist/mcp/nexum-tools.js +39 -22
  44. package/dist/mcp/nexum-tools.js.map +1 -1
  45. package/dist/nexum-analysis/enqueue.d.ts.map +1 -1
  46. package/dist/nexum-analysis/enqueue.js +2 -1
  47. package/dist/nexum-analysis/enqueue.js.map +1 -1
  48. package/dist/nexum-analysis/knowledge-read.d.ts +45 -0
  49. package/dist/nexum-analysis/knowledge-read.d.ts.map +1 -0
  50. package/dist/nexum-analysis/knowledge-read.js +26 -0
  51. package/dist/nexum-analysis/knowledge-read.js.map +1 -0
  52. package/dist/openapi/openapi.json +18354 -17718
  53. package/dist/patches/access.d.ts +15 -0
  54. package/dist/patches/access.d.ts.map +1 -0
  55. package/dist/patches/access.js +27 -0
  56. package/dist/patches/access.js.map +1 -0
  57. package/dist/patches/engine.d.ts +67 -0
  58. package/dist/patches/engine.d.ts.map +1 -0
  59. package/dist/patches/engine.js +966 -0
  60. package/dist/patches/engine.js.map +1 -0
  61. package/dist/patches/guards.d.ts +23 -0
  62. package/dist/patches/guards.d.ts.map +1 -0
  63. package/dist/patches/guards.js +77 -0
  64. package/dist/patches/guards.js.map +1 -0
  65. package/dist/patches/legacy-rows.d.ts +56 -0
  66. package/dist/patches/legacy-rows.d.ts.map +1 -0
  67. package/dist/patches/legacy-rows.js +162 -0
  68. package/dist/patches/legacy-rows.js.map +1 -0
  69. package/dist/patches/ops.d.ts +24 -0
  70. package/dist/patches/ops.d.ts.map +1 -0
  71. package/dist/patches/ops.js +204 -0
  72. package/dist/patches/ops.js.map +1 -0
  73. package/dist/patches/parse.d.ts +5 -0
  74. package/dist/patches/parse.d.ts.map +1 -0
  75. package/dist/patches/parse.js +323 -0
  76. package/dist/patches/parse.js.map +1 -0
  77. package/dist/patches/paths.d.ts +38 -0
  78. package/dist/patches/paths.d.ts.map +1 -0
  79. package/dist/patches/paths.js +204 -0
  80. package/dist/patches/paths.js.map +1 -0
  81. package/dist/patches/service.d.ts +16 -0
  82. package/dist/patches/service.d.ts.map +1 -0
  83. package/dist/patches/service.js +128 -0
  84. package/dist/patches/service.js.map +1 -0
  85. package/dist/patches/store.d.ts +87 -0
  86. package/dist/patches/store.d.ts.map +1 -0
  87. package/dist/patches/store.js +27 -0
  88. package/dist/patches/store.js.map +1 -0
  89. package/dist/patches/types.d.ts +112 -0
  90. package/dist/patches/types.d.ts.map +1 -0
  91. package/dist/patches/types.js +5 -0
  92. package/dist/patches/types.js.map +1 -0
  93. package/dist/platform.d.ts +8 -0
  94. package/dist/platform.d.ts.map +1 -1
  95. package/dist/platform.js +98 -4
  96. package/dist/platform.js.map +1 -1
  97. package/dist/routes/anomaly.d.ts +5 -0
  98. package/dist/routes/anomaly.d.ts.map +1 -0
  99. package/dist/routes/anomaly.js +308 -0
  100. package/dist/routes/anomaly.js.map +1 -0
  101. package/dist/routes/data.d.ts.map +1 -1
  102. package/dist/routes/data.js +190 -202
  103. package/dist/routes/data.js.map +1 -1
  104. package/dist/routes/knowledge.d.ts.map +1 -1
  105. package/dist/routes/knowledge.js +6 -22
  106. package/dist/routes/knowledge.js.map +1 -1
  107. package/dist/routes/metadata.d.ts.map +1 -1
  108. package/dist/routes/metadata.js +28 -1
  109. package/dist/routes/metadata.js.map +1 -1
  110. package/dist/routes/patches.d.ts +7 -0
  111. package/dist/routes/patches.d.ts.map +1 -0
  112. package/dist/routes/patches.js +111 -0
  113. package/dist/routes/patches.js.map +1 -0
  114. package/dist/routes/subject-roots-backfill.d.ts +4 -0
  115. package/dist/routes/subject-roots-backfill.d.ts.map +1 -0
  116. package/dist/routes/subject-roots-backfill.js +15 -0
  117. package/dist/routes/subject-roots-backfill.js.map +1 -0
  118. package/dist/single-read-discriminator.d.ts +17 -0
  119. package/dist/single-read-discriminator.d.ts.map +1 -0
  120. package/dist/single-read-discriminator.js +67 -0
  121. package/dist/single-read-discriminator.js.map +1 -0
  122. package/dist/subject-roots-backfill.d.ts +24 -0
  123. package/dist/subject-roots-backfill.d.ts.map +1 -0
  124. package/dist/subject-roots-backfill.js +133 -0
  125. package/dist/subject-roots-backfill.js.map +1 -0
  126. package/dist/write-precondition.d.ts +5 -1
  127. package/dist/write-precondition.d.ts.map +1 -1
  128. package/dist/write-precondition.js +11 -3
  129. package/dist/write-precondition.js.map +1 -1
  130. package/dist/writes/content-write.d.ts +170 -0
  131. package/dist/writes/content-write.d.ts.map +1 -0
  132. package/dist/writes/content-write.js +569 -0
  133. package/dist/writes/content-write.js.map +1 -0
  134. package/dist/writes/effects.d.ts +13 -0
  135. package/dist/writes/effects.d.ts.map +1 -0
  136. package/dist/writes/effects.js +28 -0
  137. package/dist/writes/effects.js.map +1 -0
  138. package/dist/writes/error-shape.d.ts +11 -0
  139. package/dist/writes/error-shape.d.ts.map +1 -0
  140. package/dist/writes/error-shape.js +100 -0
  141. package/dist/writes/error-shape.js.map +1 -0
  142. package/dist/writes/receipt-store.d.ts +81 -0
  143. package/dist/writes/receipt-store.d.ts.map +1 -0
  144. package/dist/writes/receipt-store.js +171 -0
  145. package/dist/writes/receipt-store.js.map +1 -0
  146. package/dist/writes/worker.d.ts +9 -0
  147. package/dist/writes/worker.d.ts.map +1 -0
  148. package/dist/writes/worker.js +20 -0
  149. package/dist/writes/worker.js.map +1 -0
  150. package/openapi/openapi.json +18354 -17718
  151. 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,5 @@
1
+ /**
2
+ * MX-PATCH-01 — a patch request repairs stored rows: `select`, ordered `ops`, optional `guards`.
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/patches/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -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;