@amalgm/live 0.2.27 → 0.2.29
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/PURPOSE.md +38 -25
- package/README.md +1 -2
- package/dist/contracts/index.d.ts +0 -1
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/contracts/index.js +0 -1
- package/dist/contracts/index.js.map +1 -1
- package/dist/detection/record-proposal.d.ts +3 -2
- package/dist/detection/record-proposal.d.ts.map +1 -1
- package/dist/detection/record-proposal.js +9 -7
- package/dist/detection/record-proposal.js.map +1 -1
- package/dist/entities/cloud.d.ts.map +1 -1
- package/dist/entities/cloud.js +4 -1
- package/dist/entities/cloud.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/machines/index.d.ts +0 -2
- package/dist/machines/index.d.ts.map +1 -1
- package/dist/machines/index.js +0 -2
- package/dist/machines/index.js.map +1 -1
- package/dist/records/authority.d.ts +23 -0
- package/dist/records/authority.d.ts.map +1 -0
- package/dist/records/authority.js +28 -0
- package/dist/records/authority.js.map +1 -0
- package/dist/records/codec.d.ts +6 -0
- package/dist/records/codec.d.ts.map +1 -0
- package/dist/records/codec.js +42 -0
- package/dist/records/codec.js.map +1 -0
- package/dist/records/contracts.d.ts +46 -0
- package/dist/records/contracts.d.ts.map +1 -0
- package/dist/records/contracts.js +114 -0
- package/dist/records/contracts.js.map +1 -0
- package/dist/records/inbox.d.ts +18 -0
- package/dist/records/inbox.d.ts.map +1 -0
- package/dist/records/inbox.js +34 -0
- package/dist/records/inbox.js.map +1 -0
- package/dist/records/index.d.ts +7 -0
- package/dist/records/index.d.ts.map +1 -0
- package/dist/records/index.js +7 -0
- package/dist/records/index.js.map +1 -0
- package/dist/records/outbox.d.ts +20 -0
- package/dist/records/outbox.d.ts.map +1 -0
- package/dist/records/outbox.js +44 -0
- package/dist/records/outbox.js.map +1 -0
- package/dist/registration/user-ground.d.ts +4 -4
- package/dist/registration/user-ground.d.ts.map +1 -1
- package/dist/registration/user-ground.js +8 -3
- package/dist/registration/user-ground.js.map +1 -1
- package/dist-cjs/contracts/binding.js +26 -0
- package/dist-cjs/contracts/binding.js.map +1 -0
- package/dist-cjs/contracts/content.js +99 -0
- package/dist-cjs/contracts/content.js.map +1 -0
- package/dist-cjs/contracts/docs.js +56 -0
- package/dist-cjs/contracts/docs.js.map +1 -0
- package/dist-cjs/contracts/events.js +44 -0
- package/dist-cjs/contracts/events.js.map +1 -0
- package/dist-cjs/contracts/frames/gateway.js +39 -0
- package/dist-cjs/contracts/frames/gateway.js.map +1 -0
- package/dist-cjs/contracts/frames/stream.js +20 -0
- package/dist-cjs/contracts/frames/stream.js.map +1 -0
- package/dist-cjs/contracts/frames/tunnel.js +60 -0
- package/dist-cjs/contracts/frames/tunnel.js.map +1 -0
- package/dist-cjs/contracts/index.js +34 -0
- package/dist-cjs/contracts/index.js.map +1 -0
- package/dist-cjs/contracts/presence.js +38 -0
- package/dist-cjs/contracts/presence.js.map +1 -0
- package/dist-cjs/contracts/resources.js +114 -0
- package/dist-cjs/contracts/resources.js.map +1 -0
- package/dist-cjs/contracts/snapshot.js +31 -0
- package/dist-cjs/contracts/snapshot.js.map +1 -0
- package/dist-cjs/contracts/validate.js +34 -0
- package/dist-cjs/contracts/validate.js.map +1 -0
- package/dist-cjs/detection/adapter-contract.js +168 -0
- package/dist-cjs/detection/adapter-contract.js.map +1 -0
- package/dist-cjs/detection/batch.js +71 -0
- package/dist-cjs/detection/batch.js.map +1 -0
- package/dist-cjs/detection/classify.js +48 -0
- package/dist-cjs/detection/classify.js.map +1 -0
- package/dist-cjs/detection/content.js +122 -0
- package/dist-cjs/detection/content.js.map +1 -0
- package/dist-cjs/detection/continuity.js +88 -0
- package/dist-cjs/detection/continuity.js.map +1 -0
- package/dist-cjs/detection/diff.js +193 -0
- package/dist-cjs/detection/diff.js.map +1 -0
- package/dist-cjs/detection/echo.js +25 -0
- package/dist-cjs/detection/echo.js.map +1 -0
- package/dist-cjs/detection/enrollment.js +189 -0
- package/dist-cjs/detection/enrollment.js.map +1 -0
- package/dist-cjs/detection/index.js +57 -0
- package/dist-cjs/detection/index.js.map +1 -0
- package/dist-cjs/detection/record-proposal.js +170 -0
- package/dist-cjs/detection/record-proposal.js.map +1 -0
- package/dist-cjs/detection/refusal.js +44 -0
- package/dist-cjs/detection/refusal.js.map +1 -0
- package/dist-cjs/detection/repository.js +67 -0
- package/dist-cjs/detection/repository.js.map +1 -0
- package/dist-cjs/detection/territory.js +82 -0
- package/dist-cjs/detection/territory.js.map +1 -0
- package/dist-cjs/detection/watch-boundary.js +51 -0
- package/dist-cjs/detection/watch-boundary.js.map +1 -0
- package/dist-cjs/entities/bytes.js +92 -0
- package/dist-cjs/entities/bytes.js.map +1 -0
- package/dist-cjs/entities/cloud.js +174 -0
- package/dist-cjs/entities/cloud.js.map +1 -0
- package/dist-cjs/entities/index.js +39 -0
- package/dist-cjs/entities/index.js.map +1 -0
- package/dist-cjs/entities/moves.js +85 -0
- package/dist-cjs/entities/moves.js.map +1 -0
- package/dist-cjs/entities/repo-states.js +256 -0
- package/dist-cjs/entities/repo-states.js.map +1 -0
- package/dist-cjs/entities/rules.js +216 -0
- package/dist-cjs/entities/rules.js.map +1 -0
- package/dist-cjs/entities/types.js +44 -0
- package/dist-cjs/entities/types.js.map +1 -0
- package/dist-cjs/files/commands.js +120 -0
- package/dist-cjs/files/commands.js.map +1 -0
- package/dist-cjs/files/index.js +19 -0
- package/dist-cjs/files/index.js.map +1 -0
- package/dist-cjs/index.js +39 -0
- package/dist-cjs/index.js.map +1 -0
- package/dist-cjs/machines/arbitration.js +41 -0
- package/dist-cjs/machines/arbitration.js.map +1 -0
- package/dist-cjs/machines/backoff.js +38 -0
- package/dist-cjs/machines/backoff.js.map +1 -0
- package/dist-cjs/machines/bootstrap.js +110 -0
- package/dist-cjs/machines/bootstrap.js.map +1 -0
- package/dist-cjs/machines/chunks.js +72 -0
- package/dist-cjs/machines/chunks.js.map +1 -0
- package/dist-cjs/machines/index.js +28 -0
- package/dist-cjs/machines/index.js.map +1 -0
- package/dist-cjs/machines/presence.js +53 -0
- package/dist-cjs/machines/presence.js.map +1 -0
- package/dist-cjs/merge/index.js +25 -0
- package/dist-cjs/merge/index.js.map +1 -0
- package/dist-cjs/merge/merge3.js +191 -0
- package/dist-cjs/merge/merge3.js.map +1 -0
- package/dist-cjs/package.json +1 -0
- package/dist-cjs/records/authority.js +31 -0
- package/dist-cjs/records/authority.js.map +1 -0
- package/dist-cjs/records/codec.js +48 -0
- package/dist-cjs/records/codec.js.map +1 -0
- package/dist-cjs/records/contracts.js +121 -0
- package/dist-cjs/records/contracts.js.map +1 -0
- package/dist-cjs/records/inbox.js +37 -0
- package/dist-cjs/records/inbox.js.map +1 -0
- package/dist-cjs/records/index.js +23 -0
- package/dist-cjs/records/index.js.map +1 -0
- package/dist-cjs/records/outbox.js +48 -0
- package/dist-cjs/records/outbox.js.map +1 -0
- package/dist-cjs/registration/index.js +19 -0
- package/dist-cjs/registration/index.js.map +1 -0
- package/dist-cjs/registration/user-ground.js +183 -0
- package/dist-cjs/registration/user-ground.js.map +1 -0
- package/dist-cjs/transfer/artifacts.js +75 -0
- package/dist-cjs/transfer/artifacts.js.map +1 -0
- package/dist-cjs/transfer/batches.js +44 -0
- package/dist-cjs/transfer/batches.js.map +1 -0
- package/dist-cjs/transfer/download.js +88 -0
- package/dist-cjs/transfer/download.js.map +1 -0
- package/dist-cjs/transfer/index.js +21 -0
- package/dist-cjs/transfer/index.js.map +1 -0
- package/dist-cjs/transfer/parallel.js +35 -0
- package/dist-cjs/transfer/parallel.js.map +1 -0
- package/dist-cjs/transfer/upload.js +161 -0
- package/dist-cjs/transfer/upload.js.map +1 -0
- package/dist-cjs/watching/coverage.js +54 -0
- package/dist-cjs/watching/coverage.js.map +1 -0
- package/dist-cjs/watching/index.js +24 -0
- package/dist-cjs/watching/index.js.map +1 -0
- package/dist-cjs/watching/suspicion.js +105 -0
- package/dist-cjs/watching/suspicion.js.map +1 -0
- package/dist-cjs/workspace/api.js +66 -0
- package/dist-cjs/workspace/api.js.map +1 -0
- package/dist-cjs/workspace/identity.js +32 -0
- package/dist-cjs/workspace/identity.js.map +1 -0
- package/dist-cjs/workspace/index.js +14 -0
- package/dist-cjs/workspace/index.js.map +1 -0
- package/dist-cjs/workspace/memory-store.js +21 -0
- package/dist-cjs/workspace/memory-store.js.map +1 -0
- package/dist-cjs/workspace/registry.js +98 -0
- package/dist-cjs/workspace/registry.js.map +1 -0
- package/dist-cjs/workspace/types.js +3 -0
- package/dist-cjs/workspace/types.js.map +1 -0
- package/package.json +30 -8
- package/dist/contracts/mutation.d.ts +0 -51
- package/dist/contracts/mutation.d.ts.map +0 -1
- package/dist/contracts/mutation.js +0 -55
- package/dist/contracts/mutation.js.map +0 -1
- package/dist/machines/journal.d.ts +0 -63
- package/dist/machines/journal.d.ts.map +0 -1
- package/dist/machines/journal.js +0 -71
- package/dist/machines/journal.js.map +0 -1
- package/dist/machines/ordering.d.ts +0 -53
- package/dist/machines/ordering.d.ts.map +0 -1
- package/dist/machines/ordering.js +0 -87
- package/dist/machines/ordering.js.map +0 -1
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Detection enrollment policies.
|
|
4
|
+
*
|
|
5
|
+
* Current user ground enrolls everything except structural local state and
|
|
6
|
+
* paths excluded by its tracked `.amalgmignore`; `.gitignore` never decides
|
|
7
|
+
* Amalgm enrollment. `defaultShouldEnroll` remains only as the older explicit
|
|
8
|
+
* registration policy for additive API compatibility. Current portable paths
|
|
9
|
+
* already use `/`; a host converts its native separator at the boundary. A
|
|
10
|
+
* literal `\\` is therefore preserved as part of a POSIX filename. Both
|
|
11
|
+
* policies are pure strings-in/verdict-out and never inspect disk themselves.
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.defaultShouldEnroll = exports.DEFAULT_AMALGM_IGNORE = exports.AMALGM_IGNORE_FILE = exports.AMALGM_CONTROL_DIRECTORY = void 0;
|
|
15
|
+
exports.normalizedRelativePath = normalizedRelativePath;
|
|
16
|
+
exports.isAmalgmControlPath = isAmalgmControlPath;
|
|
17
|
+
exports.isSqliteCoordinationPath = isSqliteCoordinationPath;
|
|
18
|
+
exports.createUserGroundEnrollmentPolicy = createUserGroundEnrollmentPolicy;
|
|
19
|
+
/** The Git-like names at the user-ground boundary. Structural coordination
|
|
20
|
+
* state is local and cannot be negated by user policy; the ignore file is
|
|
21
|
+
* portable ground so every machine evaluates the same user rules. */
|
|
22
|
+
exports.AMALGM_CONTROL_DIRECTORY = '.amalgm';
|
|
23
|
+
exports.AMALGM_IGNORE_FILE = '.amalgmignore';
|
|
24
|
+
exports.DEFAULT_AMALGM_IGNORE = `/${exports.AMALGM_CONTROL_DIRECTORY}/\n`;
|
|
25
|
+
const EXCLUDED_DIRECTORIES = new Set([
|
|
26
|
+
'.amalgm',
|
|
27
|
+
'.aws',
|
|
28
|
+
'.cache',
|
|
29
|
+
'.docker',
|
|
30
|
+
'.git',
|
|
31
|
+
'.gnupg',
|
|
32
|
+
'.gradle',
|
|
33
|
+
'.hg',
|
|
34
|
+
'.kube',
|
|
35
|
+
'.mypy_cache',
|
|
36
|
+
'.next',
|
|
37
|
+
'.nyc_output',
|
|
38
|
+
'.parcel-cache',
|
|
39
|
+
'.pytest_cache',
|
|
40
|
+
'.ruff_cache',
|
|
41
|
+
'.ssh',
|
|
42
|
+
'.svn',
|
|
43
|
+
'.svelte-kit',
|
|
44
|
+
'.turbo',
|
|
45
|
+
'.venv',
|
|
46
|
+
'.vite',
|
|
47
|
+
'__pycache__',
|
|
48
|
+
'coverage',
|
|
49
|
+
'node_modules',
|
|
50
|
+
]);
|
|
51
|
+
const EXCLUDED_FILES = new Set([
|
|
52
|
+
'.DS_Store',
|
|
53
|
+
'Thumbs.db',
|
|
54
|
+
'desktop.ini',
|
|
55
|
+
'npm-debug.log',
|
|
56
|
+
'pnpm-debug.log',
|
|
57
|
+
'yarn-debug.log',
|
|
58
|
+
'yarn-error.log',
|
|
59
|
+
]);
|
|
60
|
+
function isPrivateFile(name) {
|
|
61
|
+
if (/^\.env(?:\..+)?$/i.test(name) && !/\.example$/i.test(name))
|
|
62
|
+
return true;
|
|
63
|
+
if (/^(?:credentials?|secrets?)\.(?:json|ya?ml|toml|ini|conf)$/i.test(name))
|
|
64
|
+
return true;
|
|
65
|
+
if (/^id_(?:dsa|ecdsa|ed25519|rsa)$/i.test(name))
|
|
66
|
+
return true;
|
|
67
|
+
if (/^(?:\.git-credentials|\.netrc|\.npmrc|\.pypirc|auth\.json|kubeconfig)$/i.test(name))
|
|
68
|
+
return true;
|
|
69
|
+
if (/^(?:service[-_]?account|firebase[-_]?adminsdk).*\.json$/i.test(name))
|
|
70
|
+
return true;
|
|
71
|
+
return /\.(?:key|keystore|kdbx|p12|pfx|pem|ppk|tfstate(?:\.backup)?)$/i.test(name);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Legacy explicit-registration policy retained for additive API compatibility.
|
|
75
|
+
* Current user-ground Detect must use {@link createUserGroundEnrollmentPolicy};
|
|
76
|
+
* there are no implicit dependency, dotfile, cache, or secret exclusions.
|
|
77
|
+
* Both separators are path separators; '' never enrolls.
|
|
78
|
+
*
|
|
79
|
+
* @deprecated Use `createUserGroundEnrollmentPolicy` for current user ground.
|
|
80
|
+
*/
|
|
81
|
+
const defaultShouldEnroll = (relPath) => {
|
|
82
|
+
const parts = normalizedRelativePath(String(relPath || '').replace(/\\/g, '/')).split('/').filter(Boolean);
|
|
83
|
+
const name = parts.at(-1);
|
|
84
|
+
if (name === undefined || parts.some((part) => EXCLUDED_DIRECTORIES.has(part)))
|
|
85
|
+
return false;
|
|
86
|
+
if (EXCLUDED_FILES.has(name) || isPrivateFile(name))
|
|
87
|
+
return false;
|
|
88
|
+
return !name.startsWith('.#') && !name.endsWith('~') && !/\.(?:swp|swo)$/i.test(name);
|
|
89
|
+
};
|
|
90
|
+
exports.defaultShouldEnroll = defaultShouldEnroll;
|
|
91
|
+
/**
|
|
92
|
+
* One normalized spelling for portable enrollment and ignore matching.
|
|
93
|
+
* Portable relative paths use `/`. Do not reinterpret `\\`: it is a valid,
|
|
94
|
+
* literal filename character on POSIX after the host has crossed this seam.
|
|
95
|
+
*/
|
|
96
|
+
function normalizedRelativePath(relPath) {
|
|
97
|
+
return String(relPath || '')
|
|
98
|
+
.replace(/^\.\//, '')
|
|
99
|
+
.replace(/^\/+|\/+$/g, '')
|
|
100
|
+
.replace(/\/{2,}/g, '/');
|
|
101
|
+
}
|
|
102
|
+
/** `.amalgm/` is local control state wherever a registered tree is rooted. */
|
|
103
|
+
function isAmalgmControlPath(relPath) {
|
|
104
|
+
return normalizedRelativePath(relPath).split('/').includes(exports.AMALGM_CONTROL_DIRECTORY);
|
|
105
|
+
}
|
|
106
|
+
/** SQLite's WAL, shared-memory, and rollback-journal files coordinate one
|
|
107
|
+
* local database connection. They are not a portable copy of the database. */
|
|
108
|
+
function isSqliteCoordinationPath(relPath) {
|
|
109
|
+
const name = normalizedRelativePath(relPath).split('/').at(-1) ?? '';
|
|
110
|
+
return /\.(?:db|sqlite|sqlite3)-(?:wal|shm|journal)$/i.test(name);
|
|
111
|
+
}
|
|
112
|
+
function escapeRegex(character) {
|
|
113
|
+
return /[\\^$.*+?()[\]{}|]/.test(character) ? `\\${character}` : character;
|
|
114
|
+
}
|
|
115
|
+
function globExpression(pattern) {
|
|
116
|
+
let expression = '';
|
|
117
|
+
for (let index = 0; index < pattern.length; index += 1) {
|
|
118
|
+
const character = pattern[index];
|
|
119
|
+
if (character === '*') {
|
|
120
|
+
if (pattern[index + 1] === '*') {
|
|
121
|
+
while (pattern[index + 1] === '*')
|
|
122
|
+
index += 1;
|
|
123
|
+
if (pattern[index + 1] === '/') {
|
|
124
|
+
index += 1;
|
|
125
|
+
expression += '(?:.*/)?';
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
expression += '.*';
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
expression += '[^/]*';
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
else if (character === '?') {
|
|
136
|
+
expression += '[^/]';
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
expression += escapeRegex(character);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return expression;
|
|
143
|
+
}
|
|
144
|
+
function ignoreRule(line) {
|
|
145
|
+
let value = line.trim();
|
|
146
|
+
if (!value || value.startsWith('#'))
|
|
147
|
+
return null;
|
|
148
|
+
let negated = false;
|
|
149
|
+
if (value.startsWith('!')) {
|
|
150
|
+
negated = true;
|
|
151
|
+
value = value.slice(1);
|
|
152
|
+
}
|
|
153
|
+
if (!value)
|
|
154
|
+
return null;
|
|
155
|
+
const anchored = value.startsWith('/');
|
|
156
|
+
if (anchored)
|
|
157
|
+
value = value.slice(1);
|
|
158
|
+
if (value.endsWith('/'))
|
|
159
|
+
value = value.slice(0, -1);
|
|
160
|
+
if (!value)
|
|
161
|
+
return null;
|
|
162
|
+
const body = globExpression(value);
|
|
163
|
+
const prefix = anchored || value.includes('/') ? '^' : '(?:^|/)';
|
|
164
|
+
return { negated, expression: new RegExp(`${prefix}${body}(?:$|/)`) };
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Compile the root `.amalgmignore` for a user ground. Rules are ordered and
|
|
168
|
+
* `!` negates a prior user rule. Reserved control state and transient SQLite
|
|
169
|
+
* coordination files are structural exclusions; every other path is ground
|
|
170
|
+
* unless this tracked file excludes it. The policy file itself always travels.
|
|
171
|
+
*/
|
|
172
|
+
function createUserGroundEnrollmentPolicy(ignoreText = '') {
|
|
173
|
+
const rules = String(ignoreText).split(/\r?\n/).map(ignoreRule)
|
|
174
|
+
.filter((rule) => rule !== null);
|
|
175
|
+
return (input) => {
|
|
176
|
+
const relPath = normalizedRelativePath(input);
|
|
177
|
+
if (!relPath || isAmalgmControlPath(relPath) || isSqliteCoordinationPath(relPath))
|
|
178
|
+
return false;
|
|
179
|
+
if (relPath === exports.AMALGM_IGNORE_FILE)
|
|
180
|
+
return true;
|
|
181
|
+
let excluded = false;
|
|
182
|
+
for (const rule of rules) {
|
|
183
|
+
if (rule.expression.test(relPath))
|
|
184
|
+
excluded = !rule.negated;
|
|
185
|
+
}
|
|
186
|
+
return !excluded;
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=enrollment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enrollment.js","sourceRoot":"","sources":["../../src/detection/enrollment.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Detection — the pure cores that turn observed disk evidence into facts.
|
|
4
|
+
* Normative sources:
|
|
5
|
+
* entity-model.md (identity axioms, the two continuity witnesses) and
|
|
6
|
+
* entity-implementation.md (the ratified seams).
|
|
7
|
+
*
|
|
8
|
+
* Everything here is rows and entries in, verdicts out. Walking disk,
|
|
9
|
+
* hashing bytes, opening watchers, and writing stores are the host's;
|
|
10
|
+
* the host injects its answers (a stat, a channel row, an enrollment
|
|
11
|
+
* policy) and this layer owns only the laws:
|
|
12
|
+
*
|
|
13
|
+
* - `adapter-contract` the seven rails, the ratified detect socket,
|
|
14
|
+
* descriptor conviction, the three-state truth
|
|
15
|
+
* judgment, the reference adapter
|
|
16
|
+
* - `classify` text/binary from detect's own read evidence
|
|
17
|
+
* - `refusal` declined-vs-broken, named where it is raised
|
|
18
|
+
* - `enrollment` tracked user-ground policy plus legacy compatibility
|
|
19
|
+
* - `diff` the compare functions: file/dir/link identity
|
|
20
|
+
* - `continuity` root rescue and the undecided address
|
|
21
|
+
* - `watch-boundary` generation-safe Watch input and coverage output
|
|
22
|
+
* - `territory` nearest-repository recorder selection
|
|
23
|
+
* - `record-proposal` the exact Detect-to-Record contract
|
|
24
|
+
* - `batch` net-difference planning and Watch settlement
|
|
25
|
+
* - `content` text/binary/link replay from one captured read
|
|
26
|
+
* - `repository` verified Card + Checkpoint transport planning
|
|
27
|
+
* - `echo` incoming Apply equality without suppression
|
|
28
|
+
*/
|
|
29
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
30
|
+
if (k2 === undefined) k2 = k;
|
|
31
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
32
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
33
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
34
|
+
}
|
|
35
|
+
Object.defineProperty(o, k2, desc);
|
|
36
|
+
}) : (function(o, m, k, k2) {
|
|
37
|
+
if (k2 === undefined) k2 = k;
|
|
38
|
+
o[k2] = m[k];
|
|
39
|
+
}));
|
|
40
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
41
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
42
|
+
};
|
|
43
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
+
__exportStar(require("./adapter-contract.js"), exports);
|
|
45
|
+
__exportStar(require("./batch.js"), exports);
|
|
46
|
+
__exportStar(require("./classify.js"), exports);
|
|
47
|
+
__exportStar(require("./continuity.js"), exports);
|
|
48
|
+
__exportStar(require("./content.js"), exports);
|
|
49
|
+
__exportStar(require("./diff.js"), exports);
|
|
50
|
+
__exportStar(require("./echo.js"), exports);
|
|
51
|
+
__exportStar(require("./enrollment.js"), exports);
|
|
52
|
+
__exportStar(require("./record-proposal.js"), exports);
|
|
53
|
+
__exportStar(require("./repository.js"), exports);
|
|
54
|
+
__exportStar(require("./refusal.js"), exports);
|
|
55
|
+
__exportStar(require("./territory.js"), exports);
|
|
56
|
+
__exportStar(require("./watch-boundary.js"), exports);
|
|
57
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/detection/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;;;;;;;;;;;;;;;;AAEH,wDAAsC;AACtC,6CAA2B;AAC3B,gDAA8B;AAC9B,kDAAgC;AAChC,+CAA6B;AAC7B,4CAA0B;AAC1B,4CAA0B;AAC1B,kDAAgC;AAChC,uDAAqC;AACrC,kDAAgC;AAChC,+CAA6B;AAC7B,iDAA+B;AAC/B,sDAAoC"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Detect's exact output to Record.
|
|
4
|
+
*
|
|
5
|
+
* A proposal is not yet a durable mutation: Record assigns one mutation id,
|
|
6
|
+
* appends it atomically, and then Send publishes that same row. Detect owns the
|
|
7
|
+
* complete result and replay instruction so no later rail has to rediscover
|
|
8
|
+
* filesystem truth.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.DETECTED_CHANGE_CONTRACT = void 0;
|
|
12
|
+
exports.detectedChangeProposal = detectedChangeProposal;
|
|
13
|
+
const cloud_js_1 = require("../entities/cloud.js");
|
|
14
|
+
const types_js_1 = require("../entities/types.js");
|
|
15
|
+
const content_js_1 = require("../contracts/content.js");
|
|
16
|
+
const artifacts_js_1 = require("../transfer/artifacts.js");
|
|
17
|
+
exports.DETECTED_CHANGE_CONTRACT = 'amalgm.detected-change-proposal@1';
|
|
18
|
+
const HASH = /^[0-9a-f]{64}$/;
|
|
19
|
+
const facetsOf = (base, result) => {
|
|
20
|
+
if (base === null)
|
|
21
|
+
return ['create'];
|
|
22
|
+
const facets = [];
|
|
23
|
+
if (base.parentUUID !== result.parentUUID)
|
|
24
|
+
facets.push('move');
|
|
25
|
+
if (base.name !== result.name)
|
|
26
|
+
facets.push('rename');
|
|
27
|
+
if (base.type !== result.type)
|
|
28
|
+
facets.push('retype');
|
|
29
|
+
const resultCarriesPayload = !types_js_1.DERIVED_PAYLOAD.has(result.type) && result.type !== 'reference';
|
|
30
|
+
if ((base.payloadVersion !== result.payloadVersion && resultCarriesPayload)
|
|
31
|
+
|| (result.type === 'repo.git' && base.transportVersion !== result.transportVersion)) {
|
|
32
|
+
facets.push('content');
|
|
33
|
+
}
|
|
34
|
+
if (base.status !== result.status) {
|
|
35
|
+
if (result.status === 'trashed')
|
|
36
|
+
facets.push('trash');
|
|
37
|
+
else if (base.status === 'trashed' && result.status === 'active')
|
|
38
|
+
facets.push('restore');
|
|
39
|
+
}
|
|
40
|
+
return facets;
|
|
41
|
+
};
|
|
42
|
+
const contentRequired = (base, result, facets) => result.status === 'active'
|
|
43
|
+
&& (base === null || facets.includes('content') || facets.includes('retype'))
|
|
44
|
+
&& ['file.text', 'file.binary', 'link', 'repo.git'].includes(result.type);
|
|
45
|
+
const validateReplay = (base, result, facets, replay) => {
|
|
46
|
+
const needsContent = contentRequired(base, result, facets);
|
|
47
|
+
if (!needsContent) {
|
|
48
|
+
if (replay.kind !== 'structure') {
|
|
49
|
+
throw new Error('a structural-only detected change must use structure replay');
|
|
50
|
+
}
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (replay.kind !== result.type) {
|
|
54
|
+
throw new Error(`detected ${result.type} content cannot use ${replay.kind} replay`);
|
|
55
|
+
}
|
|
56
|
+
if (result.payloadVersion === null) {
|
|
57
|
+
throw new Error(`detected ${result.type} content has no result payload version`);
|
|
58
|
+
}
|
|
59
|
+
switch (replay.kind) {
|
|
60
|
+
case 'file.text':
|
|
61
|
+
const expectedTextBase = base?.payloadVersion && HASH.test(base.payloadVersion)
|
|
62
|
+
? base.payloadVersion
|
|
63
|
+
: null;
|
|
64
|
+
if (replay.basePayloadVersion !== expectedTextBase
|
|
65
|
+
|| replay.resultPayloadVersion !== result.payloadVersion
|
|
66
|
+
|| (replay.mode === 'delta') !== (replay.delta !== null)) {
|
|
67
|
+
throw new Error('text replay does not name the detected base and result');
|
|
68
|
+
}
|
|
69
|
+
if (!HASH.test(replay.resultPayloadVersion)
|
|
70
|
+
|| (replay.basePayloadVersion !== null && !HASH.test(replay.basePayloadVersion))) {
|
|
71
|
+
throw new Error('text replay has an invalid content head');
|
|
72
|
+
}
|
|
73
|
+
if (replay.delta !== null
|
|
74
|
+
&& (!Number.isSafeInteger(replay.delta.offset) || replay.delta.offset < 0
|
|
75
|
+
|| !Number.isSafeInteger(replay.delta.deleteBytes) || replay.delta.deleteBytes < 0
|
|
76
|
+
|| !(replay.delta.insert instanceof Uint8Array))) {
|
|
77
|
+
throw new Error('text replay has an invalid byte splice');
|
|
78
|
+
}
|
|
79
|
+
break;
|
|
80
|
+
case 'file.binary': {
|
|
81
|
+
const manifest = (0, content_js_1.checkContentManifest)(replay.manifest, result.payloadVersion);
|
|
82
|
+
if (!manifest.ok || replay.resultPayloadVersion !== result.payloadVersion) {
|
|
83
|
+
throw new Error('binary replay does not name the detected result');
|
|
84
|
+
}
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
case 'link':
|
|
88
|
+
if (typeof replay.target !== 'string'
|
|
89
|
+
|| replay.resultPayloadVersion !== result.payloadVersion
|
|
90
|
+
|| !HASH.test(replay.resultPayloadVersion)) {
|
|
91
|
+
throw new Error('link replay does not name the detected result');
|
|
92
|
+
}
|
|
93
|
+
break;
|
|
94
|
+
case 'repo.git':
|
|
95
|
+
if (replay.stateId !== result.payloadVersion
|
|
96
|
+
|| result.transportVersion === null
|
|
97
|
+
|| replay.transportVersion !== result.transportVersion
|
|
98
|
+
|| ![replay.stateId, replay.cardId, replay.checkpointId, replay.transportVersion]
|
|
99
|
+
.every((head) => HASH.test(head))
|
|
100
|
+
|| (replay.parentTransportVersion !== null && !HASH.test(replay.parentTransportVersion))
|
|
101
|
+
|| typeof replay.cardChanged !== 'boolean'
|
|
102
|
+
|| typeof replay.checkpointChanged !== 'boolean') {
|
|
103
|
+
throw new Error('repository replay does not name the detected state and transport');
|
|
104
|
+
}
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* Build one immutable proposal, or null when settled truth has the same logical
|
|
110
|
+
* version. A repository transport-only change is still meaningful because its
|
|
111
|
+
* worktree identity map is part of exact reproduction even when Card and
|
|
112
|
+
* Checkpoint IDs did not move.
|
|
113
|
+
*/
|
|
114
|
+
function detectedChangeProposal(input) {
|
|
115
|
+
const result = (0, cloud_js_1.assertRecord)(input.result);
|
|
116
|
+
const base = input.base === null ? null : (0, cloud_js_1.assertRecord)(input.base);
|
|
117
|
+
if (base !== null && base.uuid !== result.uuid) {
|
|
118
|
+
throw new Error('a detected transition cannot change entity UUID');
|
|
119
|
+
}
|
|
120
|
+
if (base === null && result.status !== 'active') {
|
|
121
|
+
throw new Error('newly detected ground must begin active');
|
|
122
|
+
}
|
|
123
|
+
if (base?.status === 'deleted') {
|
|
124
|
+
throw new Error('Detection cannot resurrect a deleted tombstone');
|
|
125
|
+
}
|
|
126
|
+
if (result.status === 'deleted') {
|
|
127
|
+
throw new Error('Detection cannot propose permanent deletion; deletion is an explicit lifecycle operation');
|
|
128
|
+
}
|
|
129
|
+
if (base?.version === result.version && base.transportVersion === result.transportVersion) {
|
|
130
|
+
const sameState = base.type === result.type
|
|
131
|
+
&& base.parentUUID === result.parentUUID
|
|
132
|
+
&& base.name === result.name
|
|
133
|
+
&& base.status === result.status
|
|
134
|
+
&& base.payloadVersion === result.payloadVersion;
|
|
135
|
+
if (!sameState)
|
|
136
|
+
throw new Error('one logical version cannot name two different entity states');
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
const facets = facetsOf(base, result);
|
|
140
|
+
if (facets.length === 0) {
|
|
141
|
+
if (base !== null && types_js_1.DERIVED_PAYLOAD.has(base.type) && base.type === result.type) {
|
|
142
|
+
// Container membership is a projection of child parentUUID values. Its
|
|
143
|
+
// derived version can move locally, but it is never an independent write
|
|
144
|
+
// that could erase a sibling created by another machine.
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
throw new Error('detected records disagree without a named logical facet');
|
|
148
|
+
}
|
|
149
|
+
if (facets.includes('trash') && input.lifecycleAuthorization !== 'trash') {
|
|
150
|
+
throw new Error('filesystem absence is not authority to Trash an entity');
|
|
151
|
+
}
|
|
152
|
+
if (facets.includes('restore') && input.lifecycleAuthorization !== 'restore') {
|
|
153
|
+
throw new Error('restoring an entity requires explicit lifecycle authority');
|
|
154
|
+
}
|
|
155
|
+
validateReplay(base, result, facets, input.replay);
|
|
156
|
+
const artifact = input.replay.kind === 'structure' ? null : (0, artifacts_js_1.artifactForRecord)(result);
|
|
157
|
+
if (input.replay.kind !== 'structure' && artifact === null) {
|
|
158
|
+
throw new Error(`detected ${result.type} replay has no transferable artifact`);
|
|
159
|
+
}
|
|
160
|
+
return Object.freeze({
|
|
161
|
+
contract: exports.DETECTED_CHANGE_CONTRACT,
|
|
162
|
+
entityId: result.uuid,
|
|
163
|
+
basedOnState: base?.version ?? null,
|
|
164
|
+
result,
|
|
165
|
+
facets: Object.freeze(facets),
|
|
166
|
+
replay: input.replay,
|
|
167
|
+
cargo: Object.freeze(artifact === null ? [] : [artifact]),
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=record-proposal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"record-proposal.js","sourceRoot":"","sources":["../../src/detection/record-proposal.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* A REFUSAL: the boundary understood the request and declined it.
|
|
4
|
+
* Ratified by entity-implementation.md ("A refusal is named where it is
|
|
5
|
+
* raised").
|
|
6
|
+
*
|
|
7
|
+
* Two things can go wrong when a caller asks for something, and they
|
|
8
|
+
* mean opposite things:
|
|
9
|
+
*
|
|
10
|
+
* a refusal the request named ground amalgm will not take — excluded
|
|
11
|
+
* by enrollment policy, already owned by another tree, not
|
|
12
|
+
* there at all. Nothing is broken. The message IS the
|
|
13
|
+
* reason and is meant to be shown to whoever asked.
|
|
14
|
+
* a fault the boundary could not do its job — a torn identity
|
|
15
|
+
* store, an unusable database, a bug. The request was
|
|
16
|
+
* fine; the installation is not.
|
|
17
|
+
*
|
|
18
|
+
* A refusal is NAMED WHERE IT IS RAISED, by the code that decided to
|
|
19
|
+
* refuse. It is never guessed later from an error's wording: matching
|
|
20
|
+
* on message text would quietly reclassify every fault as the caller's
|
|
21
|
+
* mistake the moment a message changed, and "your path is bad" is the
|
|
22
|
+
* worst possible thing to say on the day the identity store tears.
|
|
23
|
+
*
|
|
24
|
+
* Callers that must answer differently — an HTTP status, an exit code —
|
|
25
|
+
* ask `isRefusal`. Everything else stays an ordinary Error and travels
|
|
26
|
+
* to whatever handles faults. The mark is a registry symbol
|
|
27
|
+
* (`Symbol.for`), so a refusal raised by one copy of this module is
|
|
28
|
+
* recognized by every other.
|
|
29
|
+
*/
|
|
30
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
|
+
exports.refusal = refusal;
|
|
32
|
+
exports.isRefusal = isRefusal;
|
|
33
|
+
const REFUSAL = Symbol.for('amalgm.registration.refusal');
|
|
34
|
+
/** Decline a request, with the reason the caller should be shown. */
|
|
35
|
+
function refusal(message) {
|
|
36
|
+
const error = new Error(message);
|
|
37
|
+
error[REFUSAL] = true;
|
|
38
|
+
return error;
|
|
39
|
+
}
|
|
40
|
+
/** True only for an error this boundary deliberately raised as a refusal. */
|
|
41
|
+
function isRefusal(error) {
|
|
42
|
+
return Boolean(error && error[REFUSAL]);
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=refusal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refusal.js","sourceRoot":"","sources":["../../src/detection/refusal.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;;AAKH,0BAIC;AAGD,8BAEC;AAZD,MAAM,OAAO,GAAkB,MAAM,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;AAEzE,qEAAqE;AACrE,SAAgB,OAAO,CAAC,OAAe;IACrC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,CAAgC,CAAC;IAChE,KAAK,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;IACtB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,6EAA6E;AAC7E,SAAgB,SAAS,CAAC,KAAc;IACtC,OAAO,OAAO,CAAC,KAAK,IAAK,KAAiC,CAAC,OAAO,CAAC,CAAC,CAAC;AACvE,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/** Repository detection through the existing Card + Checkpoint transport. */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.captureRepositoryChange = captureRepositoryChange;
|
|
5
|
+
const repo_states_js_1 = require("../entities/repo-states.js");
|
|
6
|
+
const upload_js_1 = require("../transfer/upload.js");
|
|
7
|
+
const verifyState = (state, sha256Hex) => {
|
|
8
|
+
const cardId = (0, repo_states_js_1.deriveCardId)(state.card, sha256Hex);
|
|
9
|
+
const checkpointId = (0, repo_states_js_1.deriveCheckpointId)(state.checkpoint, sha256Hex);
|
|
10
|
+
const stateId = (0, repo_states_js_1.deriveStateId)(cardId, checkpointId, sha256Hex);
|
|
11
|
+
if (state.cardId !== cardId || state.checkpointId !== checkpointId || state.stateId !== stateId) {
|
|
12
|
+
throw new Error('repository capture IDs do not describe its Card and Checkpoint');
|
|
13
|
+
}
|
|
14
|
+
if (state.pack !== null && sha256Hex(state.pack.bytes) !== state.pack.sha256) {
|
|
15
|
+
throw new Error('repository Git pack does not match its declared hash');
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Verify a fresh full Card + Checkpoint observation and seal one incremental
|
|
20
|
+
* repository transport. Git discovery and pack construction are host effects;
|
|
21
|
+
* this function owns the portable IDs, identity-map delta, binary transport,
|
|
22
|
+
* and exact cargo head.
|
|
23
|
+
*/
|
|
24
|
+
function captureRepositoryChange(input, sha256Hex) {
|
|
25
|
+
verifyState(input.state, sha256Hex);
|
|
26
|
+
if (input.previous
|
|
27
|
+
&& new Set(input.previous.identity.map((entry) => entry.path)).size !== input.previous.identity.length) {
|
|
28
|
+
throw new Error('previous repository identity map has duplicate paths');
|
|
29
|
+
}
|
|
30
|
+
const identity = (0, repo_states_js_1.planRepositoryIdentity)(input.identity, input.previous?.identity ?? null, sha256Hex);
|
|
31
|
+
const currentIdentityHash = (0, repo_states_js_1.repositoryIdentityHash)(input.identity, sha256Hex);
|
|
32
|
+
if (input.previous?.stateId === input.state.stateId
|
|
33
|
+
&& (0, repo_states_js_1.repositoryIdentityHash)(input.previous.identity, sha256Hex) === currentIdentityHash) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
const bytes = (0, repo_states_js_1.encodeRepositoryTransport)(input.state, {
|
|
37
|
+
parentTransportVersion: input.previous?.transportVersion ?? null,
|
|
38
|
+
identityHash: identity.identityHash,
|
|
39
|
+
identityDelta: identity.identityDelta,
|
|
40
|
+
});
|
|
41
|
+
const transportVersion = sha256Hex(bytes);
|
|
42
|
+
const artifact = Object.freeze({
|
|
43
|
+
entityId: input.entityId,
|
|
44
|
+
entityType: 'repo.git',
|
|
45
|
+
kind: 'git',
|
|
46
|
+
contentHash: transportVersion,
|
|
47
|
+
});
|
|
48
|
+
const cargo = Object.freeze({
|
|
49
|
+
artifact,
|
|
50
|
+
bytes,
|
|
51
|
+
manifest: (0, upload_js_1.deriveUploadManifest)(artifact, bytes, sha256Hex),
|
|
52
|
+
});
|
|
53
|
+
return Object.freeze({
|
|
54
|
+
replay: Object.freeze({
|
|
55
|
+
kind: 'repo.git',
|
|
56
|
+
stateId: input.state.stateId,
|
|
57
|
+
cardId: input.state.cardId,
|
|
58
|
+
checkpointId: input.state.checkpointId,
|
|
59
|
+
cardChanged: input.previous?.cardId !== input.state.cardId,
|
|
60
|
+
checkpointChanged: input.previous?.checkpointId !== input.state.checkpointId,
|
|
61
|
+
parentTransportVersion: input.previous?.transportVersion ?? null,
|
|
62
|
+
transportVersion,
|
|
63
|
+
}),
|
|
64
|
+
cargo,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=repository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository.js","sourceRoot":"","sources":["../../src/detection/repository.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/** Nearest-repository ownership for one detected entity transition. */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.nearestRepository = nearestRepository;
|
|
5
|
+
exports.recorderTargets = recorderTargets;
|
|
6
|
+
/** The nearest repo at or above `uuid`; nested repositories win. */
|
|
7
|
+
function nearestRepository(uuid, byUuid) {
|
|
8
|
+
const seen = new Set();
|
|
9
|
+
let cursor = uuid;
|
|
10
|
+
while (cursor !== null) {
|
|
11
|
+
if (seen.has(cursor))
|
|
12
|
+
throw new Error(`registry corrupt: parent cycle at ${cursor}`);
|
|
13
|
+
seen.add(cursor);
|
|
14
|
+
const row = byUuid(cursor);
|
|
15
|
+
if (!row)
|
|
16
|
+
throw new Error(`no entity ${cursor}`);
|
|
17
|
+
if (row.type === 'repo.git')
|
|
18
|
+
return row;
|
|
19
|
+
cursor = row.parentUuid;
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Name every recorder whose state a transition can change.
|
|
25
|
+
*
|
|
26
|
+
* Ordinary changes outside repository territory publish on the entity UUID.
|
|
27
|
+
* A change wholly inside one repository publishes only the repository parcel.
|
|
28
|
+
* Crossing a repository boundary also publishes the entity graph transition,
|
|
29
|
+
* plus the source and/or destination repositories whose identity maps and
|
|
30
|
+
* Checkpoints changed.
|
|
31
|
+
*/
|
|
32
|
+
function recorderTargets(transition, byUuid) {
|
|
33
|
+
const { base, result } = transition;
|
|
34
|
+
if (base !== null && base.uuid !== result.uuid) {
|
|
35
|
+
throw new Error('a recorder transition cannot change entity UUID');
|
|
36
|
+
}
|
|
37
|
+
const before = nearestRepository(base?.parentUUID ?? null, byUuid);
|
|
38
|
+
const after = nearestRepository(result.parentUUID, byUuid);
|
|
39
|
+
const add = (targets, target) => {
|
|
40
|
+
if (!targets.some((candidate) => candidate.resourceId === target.resourceId))
|
|
41
|
+
targets.push(target);
|
|
42
|
+
};
|
|
43
|
+
// Every `.git` boundary starts its own repository rail, even when nested.
|
|
44
|
+
// Its enclosing repository changes only when the boundary's graph entry
|
|
45
|
+
// changes; ordinary Card/Checkpoint advancement remains on the inner rail.
|
|
46
|
+
if (base?.type === 'repo.git' || result.type === 'repo.git') {
|
|
47
|
+
const targets = [];
|
|
48
|
+
add(targets, {
|
|
49
|
+
kind: result.type === 'repo.git' ? 'repository' : 'entity',
|
|
50
|
+
resourceId: result.uuid,
|
|
51
|
+
});
|
|
52
|
+
const boundaryChanged = base === null
|
|
53
|
+
|| base.type !== result.type
|
|
54
|
+
|| base.parentUUID !== result.parentUUID
|
|
55
|
+
|| base.name !== result.name
|
|
56
|
+
|| base.status !== result.status;
|
|
57
|
+
if (boundaryChanged) {
|
|
58
|
+
if (before)
|
|
59
|
+
add(targets, { kind: 'repository', resourceId: before.uuid });
|
|
60
|
+
if (after)
|
|
61
|
+
add(targets, { kind: 'repository', resourceId: after.uuid });
|
|
62
|
+
}
|
|
63
|
+
return Object.freeze(targets);
|
|
64
|
+
}
|
|
65
|
+
if (base === null) {
|
|
66
|
+
return Object.freeze(after
|
|
67
|
+
? [{ kind: 'repository', resourceId: after.uuid }]
|
|
68
|
+
: [{ kind: 'entity', resourceId: result.uuid }]);
|
|
69
|
+
}
|
|
70
|
+
if (before?.uuid === after?.uuid) {
|
|
71
|
+
return Object.freeze(before
|
|
72
|
+
? [{ kind: 'repository', resourceId: before.uuid }]
|
|
73
|
+
: [{ kind: 'entity', resourceId: result.uuid }]);
|
|
74
|
+
}
|
|
75
|
+
const targets = [{ kind: 'entity', resourceId: result.uuid }];
|
|
76
|
+
for (const repository of [before, after]) {
|
|
77
|
+
if (repository)
|
|
78
|
+
add(targets, { kind: 'repository', resourceId: repository.uuid });
|
|
79
|
+
}
|
|
80
|
+
return Object.freeze(targets);
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=territory.js.map
|