@amalgm/live 0.2.54 → 0.2.55
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 +6 -0
- package/dist/contracts/binding.d.ts +3 -2
- package/dist/contracts/binding.d.ts.map +1 -1
- package/dist/contracts/deployments.d.ts +39 -0
- package/dist/contracts/deployments.d.ts.map +1 -0
- package/dist/contracts/deployments.js +75 -0
- package/dist/contracts/deployments.js.map +1 -0
- package/dist/contracts/index.d.ts +1 -0
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/contracts/index.js +1 -0
- package/dist/contracts/index.js.map +1 -1
- package/dist/detection/adapter-contract.d.ts +0 -33
- package/dist/detection/adapter-contract.d.ts.map +1 -1
- package/dist/detection/adapter-contract.js +0 -32
- package/dist/detection/adapter-contract.js.map +1 -1
- package/dist/detection/diff.d.ts +5 -87
- package/dist/detection/diff.d.ts.map +1 -1
- package/dist/detection/diff.js +5 -111
- package/dist/detection/diff.js.map +1 -1
- package/dist/detection/enrollment.d.ts +8 -17
- package/dist/detection/enrollment.d.ts.map +1 -1
- package/dist/detection/enrollment.js +8 -73
- package/dist/detection/enrollment.js.map +1 -1
- package/dist/detection/index.d.ts +5 -8
- package/dist/detection/index.d.ts.map +1 -1
- package/dist/detection/index.js +5 -8
- package/dist/detection/index.js.map +1 -1
- package/dist/detection/territory.d.ts +1 -27
- package/dist/detection/territory.d.ts.map +1 -1
- package/dist/detection/territory.js +1 -77
- package/dist/detection/territory.js.map +1 -1
- package/dist/transfer/cargo.d.ts +46 -12
- package/dist/transfer/cargo.d.ts.map +1 -1
- package/dist/transfer/cargo.js +52 -18
- package/dist/transfer/cargo.js.map +1 -1
- package/dist-cjs/contracts/deployments.js +81 -0
- package/dist-cjs/contracts/deployments.js.map +1 -0
- package/dist-cjs/contracts/index.js +1 -0
- package/dist-cjs/contracts/index.js.map +1 -1
- package/dist-cjs/detection/adapter-contract.js +1 -34
- package/dist-cjs/detection/adapter-contract.js.map +1 -1
- package/dist-cjs/detection/diff.js +5 -113
- package/dist-cjs/detection/diff.js.map +1 -1
- package/dist-cjs/detection/enrollment.js +9 -75
- package/dist-cjs/detection/enrollment.js.map +1 -1
- package/dist-cjs/detection/index.js +5 -8
- package/dist-cjs/detection/index.js.map +1 -1
- package/dist-cjs/detection/territory.js +1 -79
- package/dist-cjs/detection/territory.js.map +1 -1
- package/dist-cjs/transfer/cargo.js +55 -20
- package/dist-cjs/transfer/cargo.js.map +1 -1
- package/package.json +1 -1
- package/dist/detection/continuity.d.ts +0 -54
- package/dist/detection/continuity.d.ts.map +0 -1
- package/dist/detection/continuity.js +0 -85
- package/dist/detection/continuity.js.map +0 -1
- package/dist-cjs/detection/continuity.js +0 -88
- package/dist-cjs/detection/continuity.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enrollment.d.ts","sourceRoot":"","sources":["../../src/detection/enrollment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,gEAAgE;AAChE,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;AAE5D;;qEAEqE;AACrE,eAAO,MAAM,wBAAwB,YAAY,CAAC;AAClD,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAClD,eAAO,MAAM,qBAAqB,gBAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"enrollment.d.ts","sourceRoot":"","sources":["../../src/detection/enrollment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,gEAAgE;AAChE,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;AAE5D;;qEAEqE;AACrE,eAAO,MAAM,wBAAwB,YAAY,CAAC;AAClD,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAClD,eAAO,MAAM,qBAAqB,gBAAoC,CAAC;AAEvE;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAK9D;AAED,8EAA8E;AAC9E,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED;8EAC8E;AAC9E,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAGjE;AAsDD;;;;;GAKG;AACH,wBAAgB,gCAAgC,CAAC,UAAU,SAAK,GAAG,gBAAgB,CAalF"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Detection enrollment
|
|
2
|
+
* Detection enrollment policy.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
4
|
+
* User ground enrolls everything except structural local state and paths
|
|
5
|
+
* excluded by its tracked `.amalgmignore`; `.gitignore` never decides Amalgm
|
|
6
|
+
* enrollment, and there are no implicit dependency, dotfile, cache, or secret
|
|
7
|
+
* exclusions. Portable paths already use `/`; a host converts its native
|
|
8
|
+
* separator at the boundary. A literal `\\` is therefore preserved as part of
|
|
9
|
+
* a POSIX filename. The policy is pure strings-in/verdict-out and never
|
|
10
|
+
* inspects disk itself.
|
|
11
11
|
*/
|
|
12
12
|
/** The Git-like names at the user-ground boundary. Structural coordination
|
|
13
13
|
* state is local and cannot be negated by user policy; the ignore file is
|
|
@@ -15,71 +15,6 @@
|
|
|
15
15
|
export const AMALGM_CONTROL_DIRECTORY = '.amalgm';
|
|
16
16
|
export const AMALGM_IGNORE_FILE = '.amalgmignore';
|
|
17
17
|
export const DEFAULT_AMALGM_IGNORE = `/${AMALGM_CONTROL_DIRECTORY}/\n`;
|
|
18
|
-
const EXCLUDED_DIRECTORIES = new Set([
|
|
19
|
-
'.amalgm',
|
|
20
|
-
'.aws',
|
|
21
|
-
'.cache',
|
|
22
|
-
'.docker',
|
|
23
|
-
'.git',
|
|
24
|
-
'.gnupg',
|
|
25
|
-
'.gradle',
|
|
26
|
-
'.hg',
|
|
27
|
-
'.kube',
|
|
28
|
-
'.mypy_cache',
|
|
29
|
-
'.next',
|
|
30
|
-
'.nyc_output',
|
|
31
|
-
'.parcel-cache',
|
|
32
|
-
'.pytest_cache',
|
|
33
|
-
'.ruff_cache',
|
|
34
|
-
'.ssh',
|
|
35
|
-
'.svn',
|
|
36
|
-
'.svelte-kit',
|
|
37
|
-
'.turbo',
|
|
38
|
-
'.venv',
|
|
39
|
-
'.vite',
|
|
40
|
-
'__pycache__',
|
|
41
|
-
'coverage',
|
|
42
|
-
'node_modules',
|
|
43
|
-
]);
|
|
44
|
-
const EXCLUDED_FILES = new Set([
|
|
45
|
-
'.DS_Store',
|
|
46
|
-
'Thumbs.db',
|
|
47
|
-
'desktop.ini',
|
|
48
|
-
'npm-debug.log',
|
|
49
|
-
'pnpm-debug.log',
|
|
50
|
-
'yarn-debug.log',
|
|
51
|
-
'yarn-error.log',
|
|
52
|
-
]);
|
|
53
|
-
function isPrivateFile(name) {
|
|
54
|
-
if (/^\.env(?:\..+)?$/i.test(name) && !/\.example$/i.test(name))
|
|
55
|
-
return true;
|
|
56
|
-
if (/^(?:credentials?|secrets?)\.(?:json|ya?ml|toml|ini|conf)$/i.test(name))
|
|
57
|
-
return true;
|
|
58
|
-
if (/^id_(?:dsa|ecdsa|ed25519|rsa)$/i.test(name))
|
|
59
|
-
return true;
|
|
60
|
-
if (/^(?:\.git-credentials|\.netrc|\.npmrc|\.pypirc|auth\.json|kubeconfig)$/i.test(name))
|
|
61
|
-
return true;
|
|
62
|
-
if (/^(?:service[-_]?account|firebase[-_]?adminsdk).*\.json$/i.test(name))
|
|
63
|
-
return true;
|
|
64
|
-
return /\.(?:key|keystore|kdbx|p12|pfx|pem|ppk|tfstate(?:\.backup)?)$/i.test(name);
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Legacy explicit-registration policy retained for additive API compatibility.
|
|
68
|
-
* Current user-ground Detect must use {@link createUserGroundEnrollmentPolicy};
|
|
69
|
-
* there are no implicit dependency, dotfile, cache, or secret exclusions.
|
|
70
|
-
* Both separators are path separators; '' never enrolls.
|
|
71
|
-
*
|
|
72
|
-
* @deprecated Use `createUserGroundEnrollmentPolicy` for current user ground.
|
|
73
|
-
*/
|
|
74
|
-
export const defaultShouldEnroll = (relPath) => {
|
|
75
|
-
const parts = normalizedRelativePath(String(relPath || '').replace(/\\/g, '/')).split('/').filter(Boolean);
|
|
76
|
-
const name = parts.at(-1);
|
|
77
|
-
if (name === undefined || parts.some((part) => EXCLUDED_DIRECTORIES.has(part)))
|
|
78
|
-
return false;
|
|
79
|
-
if (EXCLUDED_FILES.has(name) || isPrivateFile(name))
|
|
80
|
-
return false;
|
|
81
|
-
return !name.startsWith('.#') && !name.endsWith('~') && !/\.(?:swp|swo)$/i.test(name);
|
|
82
|
-
};
|
|
83
18
|
/**
|
|
84
19
|
* One normalized spelling for portable enrollment and ignore matching.
|
|
85
20
|
* Portable relative paths use `/`. Do not reinterpret `\\`: it is a valid,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enrollment.js","sourceRoot":"","sources":["../../src/detection/enrollment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH;;qEAEqE;AACrE,MAAM,CAAC,MAAM,wBAAwB,GAAG,SAAS,CAAC;AAClD,MAAM,CAAC,MAAM,kBAAkB,GAAG,eAAe,CAAC;AAClD,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,wBAAwB,KAAK,CAAC;AAEvE
|
|
1
|
+
{"version":3,"file":"enrollment.js","sourceRoot":"","sources":["../../src/detection/enrollment.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Detection — the pure cores that turn observed disk evidence into facts.
|
|
3
3
|
* Normative sources:
|
|
4
|
-
* entity-model.md (identity axioms, the two
|
|
4
|
+
* entity-model.md (identity axioms, the two identity witnesses) and
|
|
5
5
|
* entity-implementation.md (the ratified seams).
|
|
6
6
|
*
|
|
7
7
|
* Everything here is rows and entries in, verdicts out. Walking disk,
|
|
@@ -10,15 +10,13 @@
|
|
|
10
10
|
* policy) and this layer owns only the laws:
|
|
11
11
|
*
|
|
12
12
|
* - `adapter-contract` the seven rails, the ratified detect socket,
|
|
13
|
-
* descriptor conviction
|
|
14
|
-
* judgment, the reference adapter
|
|
13
|
+
* and descriptor conviction
|
|
15
14
|
* - `classify` text/binary from detect's own read evidence
|
|
16
15
|
* - `refusal` declined-vs-broken, named where it is raised
|
|
17
|
-
* - `enrollment` tracked user-ground policy
|
|
18
|
-
* - `diff`
|
|
19
|
-
* - `continuity` root rescue and the undecided address
|
|
16
|
+
* - `enrollment` the tracked user-ground policy
|
|
17
|
+
* - `diff` directory channel identity from inode and address
|
|
20
18
|
* - `watch-boundary` generation-safe Watch input and coverage output
|
|
21
|
-
* - `territory` nearest-repository
|
|
19
|
+
* - `territory` nearest-repository ownership, indexed per graph
|
|
22
20
|
* - `record-proposal` the exact Detect-to-Record contract
|
|
23
21
|
* - `batch` net-difference planning and Watch settlement
|
|
24
22
|
* - `content` text/binary/link replay from one captured read
|
|
@@ -28,7 +26,6 @@
|
|
|
28
26
|
export * from './adapter-contract.js';
|
|
29
27
|
export * from './batch.js';
|
|
30
28
|
export * from './classify.js';
|
|
31
|
-
export * from './continuity.js';
|
|
32
29
|
export * from './content.js';
|
|
33
30
|
export * from './diff.js';
|
|
34
31
|
export * from './echo.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/detection/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/detection/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,cAAc,uBAAuB,CAAC;AACtC,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC"}
|
package/dist/detection/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Detection — the pure cores that turn observed disk evidence into facts.
|
|
3
3
|
* Normative sources:
|
|
4
|
-
* entity-model.md (identity axioms, the two
|
|
4
|
+
* entity-model.md (identity axioms, the two identity witnesses) and
|
|
5
5
|
* entity-implementation.md (the ratified seams).
|
|
6
6
|
*
|
|
7
7
|
* Everything here is rows and entries in, verdicts out. Walking disk,
|
|
@@ -10,15 +10,13 @@
|
|
|
10
10
|
* policy) and this layer owns only the laws:
|
|
11
11
|
*
|
|
12
12
|
* - `adapter-contract` the seven rails, the ratified detect socket,
|
|
13
|
-
* descriptor conviction
|
|
14
|
-
* judgment, the reference adapter
|
|
13
|
+
* and descriptor conviction
|
|
15
14
|
* - `classify` text/binary from detect's own read evidence
|
|
16
15
|
* - `refusal` declined-vs-broken, named where it is raised
|
|
17
|
-
* - `enrollment` tracked user-ground policy
|
|
18
|
-
* - `diff`
|
|
19
|
-
* - `continuity` root rescue and the undecided address
|
|
16
|
+
* - `enrollment` the tracked user-ground policy
|
|
17
|
+
* - `diff` directory channel identity from inode and address
|
|
20
18
|
* - `watch-boundary` generation-safe Watch input and coverage output
|
|
21
|
-
* - `territory` nearest-repository
|
|
19
|
+
* - `territory` nearest-repository ownership, indexed per graph
|
|
22
20
|
* - `record-proposal` the exact Detect-to-Record contract
|
|
23
21
|
* - `batch` net-difference planning and Watch settlement
|
|
24
22
|
* - `content` text/binary/link replay from one captured read
|
|
@@ -28,7 +26,6 @@
|
|
|
28
26
|
export * from './adapter-contract.js';
|
|
29
27
|
export * from './batch.js';
|
|
30
28
|
export * from './classify.js';
|
|
31
|
-
export * from './continuity.js';
|
|
32
29
|
export * from './content.js';
|
|
33
30
|
export * from './diff.js';
|
|
34
31
|
export * from './echo.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/detection/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/detection/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,cAAc,uBAAuB,CAAC;AACtC,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC"}
|
|
@@ -1,15 +1,5 @@
|
|
|
1
|
-
/** Nearest-repository ownership for
|
|
1
|
+
/** Nearest-repository ownership, indexed once for a whole graph. */
|
|
2
2
|
import type { CloudEntityRecord } from '../entities/cloud.js';
|
|
3
|
-
import type { EntityReadPort, EntityRow } from '../entities/types.js';
|
|
4
|
-
export interface EntityRecorderTarget {
|
|
5
|
-
readonly kind: 'entity';
|
|
6
|
-
readonly resourceId: string;
|
|
7
|
-
}
|
|
8
|
-
export interface RepositoryRecorderTarget {
|
|
9
|
-
readonly kind: 'repository';
|
|
10
|
-
readonly resourceId: string;
|
|
11
|
-
}
|
|
12
|
-
export type RecorderTarget = EntityRecorderTarget | RepositoryRecorderTarget;
|
|
13
3
|
export interface RepositoryTerritoryNode {
|
|
14
4
|
readonly uuid: string;
|
|
15
5
|
readonly type: CloudEntityRecord['type'];
|
|
@@ -29,20 +19,4 @@ export interface RepositoryTerritoryIndex<Node extends RepositoryTerritoryNode>
|
|
|
29
19
|
* owner in this index.
|
|
30
20
|
*/
|
|
31
21
|
export declare function indexRepositoryTerritory<Node extends RepositoryTerritoryNode>(nodes: readonly Node[]): RepositoryTerritoryIndex<Node>;
|
|
32
|
-
export interface RecorderTransition {
|
|
33
|
-
readonly base: Pick<CloudEntityRecord, 'uuid' | 'type' | 'parentUUID' | 'name' | 'status'> | null;
|
|
34
|
-
readonly result: Pick<CloudEntityRecord, 'uuid' | 'type' | 'parentUUID' | 'name' | 'status'>;
|
|
35
|
-
}
|
|
36
|
-
/** The nearest repo at or above `uuid`; nested repositories win. */
|
|
37
|
-
export declare function nearestRepository(uuid: string | null, byUuid: EntityReadPort['byUuid']): EntityRow | null;
|
|
38
|
-
/**
|
|
39
|
-
* Name every recorder whose state a transition can change.
|
|
40
|
-
*
|
|
41
|
-
* Ordinary changes outside repository territory publish on the entity UUID.
|
|
42
|
-
* A change wholly inside one repository publishes only the repository parcel.
|
|
43
|
-
* Crossing a repository boundary also publishes the entity graph transition,
|
|
44
|
-
* plus the source and/or destination repositories whose identity maps and
|
|
45
|
-
* Checkpoints changed.
|
|
46
|
-
*/
|
|
47
|
-
export declare function recorderTargets(transition: RecorderTransition, byUuid: EntityReadPort['byUuid']): readonly RecorderTarget[];
|
|
48
22
|
//# sourceMappingURL=territory.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"territory.d.ts","sourceRoot":"","sources":["../../src/detection/territory.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"territory.d.ts","sourceRoot":"","sources":["../../src/detection/territory.ts"],"names":[],"mappings":"AAAA,oEAAoE;AAEpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACzC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED,MAAM,WAAW,wBAAwB,CAAC,IAAI,SAAS,uBAAuB;IAC5E,gFAAgF;IAChF,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IACjC,8DAA8D;IAC9D,OAAO,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,IAAI,EAAE,CAAC;CAChD;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,SAAS,uBAAuB,EAC3E,KAAK,EAAE,SAAS,IAAI,EAAE,GACrB,wBAAwB,CAAC,IAAI,CAAC,CAuChC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Nearest-repository ownership for
|
|
1
|
+
/** Nearest-repository ownership, indexed once for a whole graph. */
|
|
2
2
|
/**
|
|
3
3
|
* Index nearest-repository territory once for a complete or boundary-trimmed
|
|
4
4
|
* graph. Hosts use this when one scan needs ownership for every row: repeated
|
|
@@ -49,80 +49,4 @@ export function indexRepositoryTerritory(nodes) {
|
|
|
49
49
|
ownedBy: (repositoryId) => Object.freeze([...(owned.get(repositoryId) ?? [])]),
|
|
50
50
|
});
|
|
51
51
|
}
|
|
52
|
-
/** The nearest repo at or above `uuid`; nested repositories win. */
|
|
53
|
-
export function nearestRepository(uuid, byUuid) {
|
|
54
|
-
const seen = new Set();
|
|
55
|
-
let cursor = uuid;
|
|
56
|
-
while (cursor !== null) {
|
|
57
|
-
if (seen.has(cursor))
|
|
58
|
-
throw new Error(`registry corrupt: parent cycle at ${cursor}`);
|
|
59
|
-
seen.add(cursor);
|
|
60
|
-
const row = byUuid(cursor);
|
|
61
|
-
if (!row)
|
|
62
|
-
throw new Error(`no entity ${cursor}`);
|
|
63
|
-
if (row.type === 'repo.git')
|
|
64
|
-
return row;
|
|
65
|
-
cursor = row.parentUuid;
|
|
66
|
-
}
|
|
67
|
-
return null;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Name every recorder whose state a transition can change.
|
|
71
|
-
*
|
|
72
|
-
* Ordinary changes outside repository territory publish on the entity UUID.
|
|
73
|
-
* A change wholly inside one repository publishes only the repository parcel.
|
|
74
|
-
* Crossing a repository boundary also publishes the entity graph transition,
|
|
75
|
-
* plus the source and/or destination repositories whose identity maps and
|
|
76
|
-
* Checkpoints changed.
|
|
77
|
-
*/
|
|
78
|
-
export function recorderTargets(transition, byUuid) {
|
|
79
|
-
const { base, result } = transition;
|
|
80
|
-
if (base !== null && base.uuid !== result.uuid) {
|
|
81
|
-
throw new Error('a recorder transition cannot change entity UUID');
|
|
82
|
-
}
|
|
83
|
-
const before = nearestRepository(base?.parentUUID ?? null, byUuid);
|
|
84
|
-
const after = nearestRepository(result.parentUUID, byUuid);
|
|
85
|
-
const add = (targets, target) => {
|
|
86
|
-
if (!targets.some((candidate) => candidate.resourceId === target.resourceId))
|
|
87
|
-
targets.push(target);
|
|
88
|
-
};
|
|
89
|
-
// Every `.git` boundary starts its own repository rail, even when nested.
|
|
90
|
-
// Its enclosing repository changes only when the boundary's graph entry
|
|
91
|
-
// changes; ordinary Card/Checkpoint advancement remains on the inner rail.
|
|
92
|
-
if (base?.type === 'repo.git' || result.type === 'repo.git') {
|
|
93
|
-
const targets = [];
|
|
94
|
-
add(targets, {
|
|
95
|
-
kind: result.type === 'repo.git' ? 'repository' : 'entity',
|
|
96
|
-
resourceId: result.uuid,
|
|
97
|
-
});
|
|
98
|
-
const boundaryChanged = base === null
|
|
99
|
-
|| base.type !== result.type
|
|
100
|
-
|| base.parentUUID !== result.parentUUID
|
|
101
|
-
|| base.name !== result.name
|
|
102
|
-
|| base.status !== result.status;
|
|
103
|
-
if (boundaryChanged) {
|
|
104
|
-
if (before)
|
|
105
|
-
add(targets, { kind: 'repository', resourceId: before.uuid });
|
|
106
|
-
if (after)
|
|
107
|
-
add(targets, { kind: 'repository', resourceId: after.uuid });
|
|
108
|
-
}
|
|
109
|
-
return Object.freeze(targets);
|
|
110
|
-
}
|
|
111
|
-
if (base === null) {
|
|
112
|
-
return Object.freeze(after
|
|
113
|
-
? [{ kind: 'repository', resourceId: after.uuid }]
|
|
114
|
-
: [{ kind: 'entity', resourceId: result.uuid }]);
|
|
115
|
-
}
|
|
116
|
-
if (before?.uuid === after?.uuid) {
|
|
117
|
-
return Object.freeze(before
|
|
118
|
-
? [{ kind: 'repository', resourceId: before.uuid }]
|
|
119
|
-
: [{ kind: 'entity', resourceId: result.uuid }]);
|
|
120
|
-
}
|
|
121
|
-
const targets = [{ kind: 'entity', resourceId: result.uuid }];
|
|
122
|
-
for (const repository of [before, after]) {
|
|
123
|
-
if (repository)
|
|
124
|
-
add(targets, { kind: 'repository', resourceId: repository.uuid });
|
|
125
|
-
}
|
|
126
|
-
return Object.freeze(targets);
|
|
127
|
-
}
|
|
128
52
|
//# sourceMappingURL=territory.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"territory.js","sourceRoot":"","sources":["../../src/detection/territory.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"territory.js","sourceRoot":"","sources":["../../src/detection/territory.ts"],"names":[],"mappings":"AAAA,oEAAoE;AAiBpE;;;;;;GAMG;AACH,MAAM,UAAU,wBAAwB,CACtC,KAAsB;IAEtB,MAAM,MAAM,GAAG,IAAI,GAAG,EAAgB,CAAC;IACvC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9F,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC9B,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC9C,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IACpC,MAAM,OAAO,GAAG,CAAC,IAAU,EAAe,EAAE;QAC1C,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;QAChE,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,8CAA8C,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC7E,CAAC;QACD,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzB,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC;QACrF,MAAM,KAAK,GAAG,MAAM,KAAK,IAAI;YAC3B,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC1D,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5B,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC7B,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IACF,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IACxC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAC1C,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjB,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,OAAO,EAAE,CAAC,IAAU,EAAE,EAAE;YACtB,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;gBACnC,MAAM,IAAI,KAAK,CAAC,yCAAyC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YACxE,CAAC;YACD,OAAO,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;QACvC,CAAC;QACD,OAAO,EAAE,CAAC,YAAoB,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;KACvF,CAAC,CAAC;AACL,CAAC"}
|
package/dist/transfer/cargo.d.ts
CHANGED
|
@@ -1,26 +1,60 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Cargo
|
|
2
|
+
* Cargo stream — cold transport of many complete small artifacts.
|
|
3
3
|
*
|
|
4
4
|
* A register journey moves file counts, not just bytes: tens of thousands
|
|
5
5
|
* of small artifacts whose per-artifact negotiation frames would dwarf the
|
|
6
|
-
* payload.
|
|
7
|
-
*
|
|
8
|
-
* count
|
|
9
|
-
*
|
|
6
|
+
* payload. The set streams as self-contained segments. Each segment carries
|
|
7
|
+
* whole artifacts — every chunk and the manifest identity — so the frame
|
|
8
|
+
* count scales with bytes moved, never with file count. Segments flow
|
|
9
|
+
* through one bounded window and never wait on one another's durability
|
|
10
|
+
* acknowledgements; the authority verifies and seals each segment
|
|
11
|
+
* independently, so an interruption loses only unacknowledged segments and
|
|
12
|
+
* a rerun resumes from the sealed inventory. Only artifacts at or below the
|
|
13
|
+
* segment byte bound ride the stream; larger artifacts keep per-artifact
|
|
14
|
+
* transfer where chunk reuse pays.
|
|
10
15
|
*/
|
|
11
|
-
export declare const
|
|
16
|
+
export declare const CARGO_SEGMENT_BYTES: number;
|
|
12
17
|
/** Bounded by the 64KiB binary-frame header law: every artifact declaration
|
|
13
18
|
* (content hash, bytes, chunk list) rides the JSON header, and 256 worst-case
|
|
14
19
|
* declarations stay under the bound with margin. The byte bound, not this
|
|
15
|
-
* count, decides the
|
|
16
|
-
export declare const
|
|
17
|
-
|
|
20
|
+
* count, decides the segment tally on real grounds. */
|
|
21
|
+
export declare const CARGO_SEGMENT_ARTIFACTS = 256;
|
|
22
|
+
/** Four full segments may be in flight at once. The window keeps the wire
|
|
23
|
+
* busy while earlier segments await the authority's per-segment durability
|
|
24
|
+
* fan-out, and worst-case payload residency (plaintext plus one encoded
|
|
25
|
+
* copy per in-flight segment) stays comfortably inside a 1-GiB runtime. */
|
|
26
|
+
export declare const CARGO_STREAM_IN_FLIGHT_BYTES: number;
|
|
27
|
+
export interface CargoItem {
|
|
28
|
+
/** Artifact identity the authority must acknowledge sealing. */
|
|
29
|
+
readonly contentHash: string;
|
|
30
|
+
/** Exact byte count of the complete artifact. */
|
|
18
31
|
readonly bytes: number;
|
|
19
32
|
}
|
|
20
|
-
export interface
|
|
33
|
+
export interface CargoSegment<T extends CargoItem> {
|
|
21
34
|
readonly items: readonly T[];
|
|
22
35
|
readonly bytes: number;
|
|
23
36
|
}
|
|
24
|
-
|
|
25
|
-
|
|
37
|
+
export interface CargoStreamPorts<T extends CargoItem> {
|
|
38
|
+
/** Transmit one self-contained segment and return the content hashes the
|
|
39
|
+
* authority sealed for it. Resolving means every returned artifact is
|
|
40
|
+
* durable; segments share nothing, so the port may be called for a later
|
|
41
|
+
* segment while earlier acknowledgements are still outstanding. */
|
|
42
|
+
send(segment: CargoSegment<T>): Promise<readonly string[]>;
|
|
43
|
+
}
|
|
44
|
+
export interface CargoStreamOptions {
|
|
45
|
+
readonly lanes?: number;
|
|
46
|
+
readonly maxInFlightBytes?: number;
|
|
47
|
+
}
|
|
48
|
+
export interface CargoStreamReceipt {
|
|
49
|
+
readonly segments: number;
|
|
50
|
+
readonly artifacts: number;
|
|
51
|
+
readonly bytes: number;
|
|
52
|
+
}
|
|
53
|
+
/** Pack items in order into segments within the byte and artifact bounds. */
|
|
54
|
+
export declare function planCargoSegments<T extends CargoItem>(items: readonly T[]): readonly CargoSegment<T>[];
|
|
55
|
+
/** Stream one cold set of small artifacts as bounded pipelined segments.
|
|
56
|
+
* Every item must come back sealed or the stream fails; a failure stops new
|
|
57
|
+
* admission, lets in-flight segments settle, and leaves their sealed work
|
|
58
|
+
* durable for the resuming rerun. */
|
|
59
|
+
export declare function streamCargo<T extends CargoItem>(items: readonly T[], ports: CargoStreamPorts<T>, options?: CargoStreamOptions): Promise<CargoStreamReceipt>;
|
|
26
60
|
//# sourceMappingURL=cargo.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cargo.d.ts","sourceRoot":"","sources":["../../src/transfer/cargo.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"cargo.d.ts","sourceRoot":"","sources":["../../src/transfer/cargo.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,eAAO,MAAM,mBAAmB,QAA4B,CAAC;AAC7D;;;uDAGuD;AACvD,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAC3C;;;2EAG2E;AAC3E,eAAO,MAAM,4BAA4B,QAA0B,CAAC;AAEpE,MAAM,WAAW,SAAS;IACxB,gEAAgE;IAChE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,iDAAiD;IACjD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,YAAY,CAAC,CAAC,SAAS,SAAS;IAC/C,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,SAAS;IACnD;;;uEAGmE;IACnE,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;CAC5D;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,6EAA6E;AAC7E,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,SAAS,EACnD,KAAK,EAAE,SAAS,CAAC,EAAE,GAClB,SAAS,YAAY,CAAC,CAAC,CAAC,EAAE,CAyB5B;AAED;;;qCAGqC;AACrC,wBAAsB,WAAW,CAAC,CAAC,SAAS,SAAS,EACnD,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAC1B,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,kBAAkB,CAAC,CAqB7B"}
|
package/dist/transfer/cargo.js
CHANGED
|
@@ -1,35 +1,49 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Cargo
|
|
2
|
+
* Cargo stream — cold transport of many complete small artifacts.
|
|
3
3
|
*
|
|
4
4
|
* A register journey moves file counts, not just bytes: tens of thousands
|
|
5
5
|
* of small artifacts whose per-artifact negotiation frames would dwarf the
|
|
6
|
-
* payload.
|
|
7
|
-
*
|
|
8
|
-
* count
|
|
9
|
-
*
|
|
6
|
+
* payload. The set streams as self-contained segments. Each segment carries
|
|
7
|
+
* whole artifacts — every chunk and the manifest identity — so the frame
|
|
8
|
+
* count scales with bytes moved, never with file count. Segments flow
|
|
9
|
+
* through one bounded window and never wait on one another's durability
|
|
10
|
+
* acknowledgements; the authority verifies and seals each segment
|
|
11
|
+
* independently, so an interruption loses only unacknowledged segments and
|
|
12
|
+
* a rerun resumes from the sealed inventory. Only artifacts at or below the
|
|
13
|
+
* segment byte bound ride the stream; larger artifacts keep per-artifact
|
|
14
|
+
* transfer where chunk reuse pays.
|
|
10
15
|
*/
|
|
11
16
|
import { FILE_TRANSFER_BATCH_BYTES } from './batches.js';
|
|
12
|
-
|
|
17
|
+
import { DEFAULT_TRANSFER_CONCURRENCY, weightedParallelForEach } from './parallel.js';
|
|
18
|
+
export const CARGO_SEGMENT_BYTES = FILE_TRANSFER_BATCH_BYTES;
|
|
13
19
|
/** Bounded by the 64KiB binary-frame header law: every artifact declaration
|
|
14
20
|
* (content hash, bytes, chunk list) rides the JSON header, and 256 worst-case
|
|
15
21
|
* declarations stay under the bound with margin. The byte bound, not this
|
|
16
|
-
* count, decides the
|
|
17
|
-
export const
|
|
18
|
-
/**
|
|
19
|
-
|
|
20
|
-
|
|
22
|
+
* count, decides the segment tally on real grounds. */
|
|
23
|
+
export const CARGO_SEGMENT_ARTIFACTS = 256;
|
|
24
|
+
/** Four full segments may be in flight at once. The window keeps the wire
|
|
25
|
+
* busy while earlier segments await the authority's per-segment durability
|
|
26
|
+
* fan-out, and worst-case payload residency (plaintext plus one encoded
|
|
27
|
+
* copy per in-flight segment) stays comfortably inside a 1-GiB runtime. */
|
|
28
|
+
export const CARGO_STREAM_IN_FLIGHT_BYTES = 4 * CARGO_SEGMENT_BYTES;
|
|
29
|
+
/** Pack items in order into segments within the byte and artifact bounds. */
|
|
30
|
+
export function planCargoSegments(items) {
|
|
31
|
+
const segments = [];
|
|
21
32
|
let current = [];
|
|
22
33
|
let bytes = 0;
|
|
23
34
|
for (const item of items) {
|
|
35
|
+
if (typeof item.contentHash !== 'string' || item.contentHash.length === 0) {
|
|
36
|
+
throw new Error('cargo item is missing its content identity');
|
|
37
|
+
}
|
|
24
38
|
if (!Number.isSafeInteger(item.bytes) || item.bytes < 0) {
|
|
25
|
-
throw new Error('cargo
|
|
39
|
+
throw new Error('cargo item byte count is invalid');
|
|
26
40
|
}
|
|
27
|
-
if (item.bytes >
|
|
28
|
-
throw new Error('cargo
|
|
41
|
+
if (item.bytes > CARGO_SEGMENT_BYTES) {
|
|
42
|
+
throw new Error('cargo item exceeds the segment byte bound');
|
|
29
43
|
}
|
|
30
44
|
if (current.length > 0
|
|
31
|
-
&& (bytes + item.bytes >
|
|
32
|
-
|
|
45
|
+
&& (bytes + item.bytes > CARGO_SEGMENT_BYTES || current.length >= CARGO_SEGMENT_ARTIFACTS)) {
|
|
46
|
+
segments.push({ items: current, bytes });
|
|
33
47
|
current = [];
|
|
34
48
|
bytes = 0;
|
|
35
49
|
}
|
|
@@ -37,7 +51,27 @@ export function planCargoWaves(items) {
|
|
|
37
51
|
bytes += item.bytes;
|
|
38
52
|
}
|
|
39
53
|
if (current.length > 0)
|
|
40
|
-
|
|
41
|
-
return
|
|
54
|
+
segments.push({ items: current, bytes });
|
|
55
|
+
return segments;
|
|
56
|
+
}
|
|
57
|
+
/** Stream one cold set of small artifacts as bounded pipelined segments.
|
|
58
|
+
* Every item must come back sealed or the stream fails; a failure stops new
|
|
59
|
+
* admission, lets in-flight segments settle, and leaves their sealed work
|
|
60
|
+
* durable for the resuming rerun. */
|
|
61
|
+
export async function streamCargo(items, ports, options = {}) {
|
|
62
|
+
const segments = planCargoSegments(items);
|
|
63
|
+
let artifacts = 0;
|
|
64
|
+
let bytes = 0;
|
|
65
|
+
await weightedParallelForEach(segments, options.lanes ?? DEFAULT_TRANSFER_CONCURRENCY, options.maxInFlightBytes ?? CARGO_STREAM_IN_FLIGHT_BYTES, (segment) => Math.max(segment.bytes, 1), async (segment) => {
|
|
66
|
+
const sealed = new Set(await ports.send(segment));
|
|
67
|
+
for (const item of segment.items) {
|
|
68
|
+
if (!sealed.has(item.contentHash)) {
|
|
69
|
+
throw new Error(`cargo authority did not seal ${item.contentHash}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
artifacts += segment.items.length;
|
|
73
|
+
bytes += segment.bytes;
|
|
74
|
+
});
|
|
75
|
+
return { segments: segments.length, artifacts, bytes };
|
|
42
76
|
}
|
|
43
77
|
//# sourceMappingURL=cargo.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cargo.js","sourceRoot":"","sources":["../../src/transfer/cargo.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"cargo.js","sourceRoot":"","sources":["../../src/transfer/cargo.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Immutable product deployments over one durable Live channel.
|
|
4
|
+
*
|
|
5
|
+
* Products own the definition carried by a deployment. Live owns the shared
|
|
6
|
+
* envelope law: one activation introduces immutable bytes and advances the
|
|
7
|
+
* subject's head atomically. The previous id records lineage; official
|
|
8
|
+
* channel order, not a client-side compare-and-swap, decides the current head.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.DEPLOYMENT_OPERATION = void 0;
|
|
12
|
+
exports.checkDeploymentActivation = checkDeploymentActivation;
|
|
13
|
+
exports.applyDeploymentActivation = applyDeploymentActivation;
|
|
14
|
+
exports.emptyDeploymentSnapshot = emptyDeploymentSnapshot;
|
|
15
|
+
const validate_js_1 = require("./validate.js");
|
|
16
|
+
exports.DEPLOYMENT_OPERATION = 'deployment.activate';
|
|
17
|
+
const EXAMPLE = '{ type: "deployment.activate", deployment: { id, subjectId, previousDeploymentId, definition, createdAt } }';
|
|
18
|
+
/** Validate the shared envelope. The owning product validates `definition`. */
|
|
19
|
+
function checkDeploymentActivation(input) {
|
|
20
|
+
if (!(0, validate_js_1.isRecord)(input) || input.type !== exports.DEPLOYMENT_OPERATION || !(0, validate_js_1.isRecord)(input.deployment)) {
|
|
21
|
+
return (0, validate_js_1.failShape)(EXAMPLE, 'the activation envelope was malformed');
|
|
22
|
+
}
|
|
23
|
+
const deployment = input.deployment;
|
|
24
|
+
if (!(0, validate_js_1.isNonEmptyString)(deployment.id) || !(0, validate_js_1.isNonEmptyString)(deployment.subjectId)) {
|
|
25
|
+
return (0, validate_js_1.failShape)(EXAMPLE, 'deployment id and subjectId must be non-empty strings');
|
|
26
|
+
}
|
|
27
|
+
if (deployment.previousDeploymentId !== null
|
|
28
|
+
&& !(0, validate_js_1.isNonEmptyString)(deployment.previousDeploymentId)) {
|
|
29
|
+
return (0, validate_js_1.failShape)(EXAMPLE, 'previousDeploymentId must be null or a non-empty string');
|
|
30
|
+
}
|
|
31
|
+
if (!(0, validate_js_1.isNonEmptyString)(deployment.createdAt)) {
|
|
32
|
+
return (0, validate_js_1.failShape)(EXAMPLE, 'createdAt must be a non-empty string');
|
|
33
|
+
}
|
|
34
|
+
return (0, validate_js_1.pass)(input);
|
|
35
|
+
}
|
|
36
|
+
function canonical(value) {
|
|
37
|
+
if (Array.isArray(value))
|
|
38
|
+
return value.map(canonical);
|
|
39
|
+
if (!(0, validate_js_1.isRecord)(value))
|
|
40
|
+
return value;
|
|
41
|
+
return Object.fromEntries(Object.entries(value)
|
|
42
|
+
.sort(([left], [right]) => left.localeCompare(right))
|
|
43
|
+
.map(([key, item]) => [key, canonical(item)]));
|
|
44
|
+
}
|
|
45
|
+
function sameDeployment(left, right) {
|
|
46
|
+
return JSON.stringify(canonical(left)) === JSON.stringify(canonical(right));
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Apply one officially ordered activation.
|
|
50
|
+
*
|
|
51
|
+
* A retry of an already-known deployment is a no-op even if newer operations
|
|
52
|
+
* have since advanced the head. Rollback therefore mints a new deployment;
|
|
53
|
+
* it never reactivates an old id. Reusing an id for different bytes is always
|
|
54
|
+
* corruption and is refused.
|
|
55
|
+
*/
|
|
56
|
+
function applyDeploymentActivation(snapshot, activation) {
|
|
57
|
+
const checked = checkDeploymentActivation(activation);
|
|
58
|
+
if (!checked.ok)
|
|
59
|
+
throw new Error(checked.error);
|
|
60
|
+
const deployment = activation.deployment;
|
|
61
|
+
const existing = snapshot.deployments[deployment.id];
|
|
62
|
+
if (existing) {
|
|
63
|
+
if (!sameDeployment(existing, deployment)) {
|
|
64
|
+
throw new Error(`Deployment id is immutable: ${deployment.id}`);
|
|
65
|
+
}
|
|
66
|
+
return snapshot;
|
|
67
|
+
}
|
|
68
|
+
return Object.freeze({
|
|
69
|
+
version: 1,
|
|
70
|
+
deployments: Object.freeze({ ...snapshot.deployments, [deployment.id]: deployment }),
|
|
71
|
+
heads: Object.freeze({ ...snapshot.heads, [deployment.subjectId]: deployment.id }),
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
function emptyDeploymentSnapshot() {
|
|
75
|
+
return Object.freeze({
|
|
76
|
+
version: 1,
|
|
77
|
+
deployments: Object.freeze({}),
|
|
78
|
+
heads: Object.freeze({}),
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=deployments.js.map
|