@amalgm/live 0.2.27 → 0.2.28
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/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 +171 -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,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerFilesWorkspace = registerFilesWorkspace;
|
|
4
|
+
exports.workspaceGraph = workspaceGraph;
|
|
5
|
+
exports.addFilesWorkspace = addFilesWorkspace;
|
|
6
|
+
const index_js_1 = require("../entities/index.js");
|
|
7
|
+
function uuid(value, label) {
|
|
8
|
+
const normalized = typeof value === 'string' ? value.trim().toLowerCase() : '';
|
|
9
|
+
if (!index_js_1.UUID_PATTERN.test(normalized))
|
|
10
|
+
throw new Error(`${label} must be a UUID`);
|
|
11
|
+
return normalized;
|
|
12
|
+
}
|
|
13
|
+
function required(value, label) {
|
|
14
|
+
const normalized = typeof value === 'string' ? value.trim() : '';
|
|
15
|
+
if (!normalized)
|
|
16
|
+
throw new Error(`${label} is required`);
|
|
17
|
+
return normalized;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Declare one external workspace. Deliberately no scan, SQLite, content, or
|
|
21
|
+
* cloud port exists here: Watch observing the rendered reference owns all
|
|
22
|
+
* enrollment and publication.
|
|
23
|
+
*/
|
|
24
|
+
async function registerFilesWorkspace(path, ports) {
|
|
25
|
+
const requestedPath = required(path, 'workspace path');
|
|
26
|
+
const inspected = await ports.inspectExternalWorkspace(requestedPath);
|
|
27
|
+
const absolutePath = required(inspected.absolutePath, 'external workspace path');
|
|
28
|
+
const workspaceName = required(inspected.name, 'workspace name');
|
|
29
|
+
const workspaceId = inspected.workspaceId === null
|
|
30
|
+
? uuid(ports.randomUuid(), 'generated workspace id')
|
|
31
|
+
: uuid(inspected.workspaceId, 'existing workspace id');
|
|
32
|
+
const declared = await ports.declareWorkspaceReference({
|
|
33
|
+
workspaceId,
|
|
34
|
+
workspaceName,
|
|
35
|
+
absolutePath,
|
|
36
|
+
});
|
|
37
|
+
return {
|
|
38
|
+
workspaceId,
|
|
39
|
+
workspaceName,
|
|
40
|
+
externalPath: absolutePath,
|
|
41
|
+
referenceName: required(declared.referenceName, 'reference name'),
|
|
42
|
+
referencePath: required(declared.referencePath, 'reference path'),
|
|
43
|
+
declared: true,
|
|
44
|
+
created: declared.created === true,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/** Select exactly one referenced materialization boundary. Its portable parent
|
|
48
|
+
* may live outside the selection; UUID, not parentlessness, is the boundary. */
|
|
49
|
+
function workspaceGraph(records, workspaceId) {
|
|
50
|
+
const normalizedId = uuid(workspaceId, 'workspace id');
|
|
51
|
+
const snapshot = (0, index_js_1.snapshotFromRecords)(records);
|
|
52
|
+
const workspace = snapshot.records.find((record) => record.uuid === normalizedId);
|
|
53
|
+
if (!workspace || workspace.status !== 'active') {
|
|
54
|
+
throw new Error(`workspace ${normalizedId} does not exist in this user's cloud registry`);
|
|
55
|
+
}
|
|
56
|
+
if (!['workspace', 'folder', 'repo.git'].includes(workspace.type)) {
|
|
57
|
+
throw new Error(`entity ${normalizedId} is not a registered workspace boundary`);
|
|
58
|
+
}
|
|
59
|
+
const references = snapshot.records.filter((record) => record.status === 'active'
|
|
60
|
+
&& record.type === 'reference' && record.payloadVersion === normalizedId);
|
|
61
|
+
if (references.length !== 1) {
|
|
62
|
+
throw new Error(`workspace ${normalizedId} must have exactly one durable reference`);
|
|
63
|
+
}
|
|
64
|
+
const included = new Set([normalizedId]);
|
|
65
|
+
let changed = true;
|
|
66
|
+
while (changed) {
|
|
67
|
+
changed = false;
|
|
68
|
+
for (const record of snapshot.records) {
|
|
69
|
+
if (record.parentUUID !== null && included.has(record.parentUUID) && !included.has(record.uuid)) {
|
|
70
|
+
included.add(record.uuid);
|
|
71
|
+
changed = true;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
workspace,
|
|
77
|
+
reference: references[0],
|
|
78
|
+
records: snapshot.records.filter((record) => included.has(record.uuid)),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/** Materialize one owned workspace root and establish Watch coverage for it. */
|
|
82
|
+
async function addFilesWorkspace(workspaceId, destinationParent, ports) {
|
|
83
|
+
const normalizedId = uuid(workspaceId, 'workspace id');
|
|
84
|
+
const destination = required(destinationParent, 'destination directory');
|
|
85
|
+
const cloud = await ports.lookupRegistry();
|
|
86
|
+
const selected = workspaceGraph(cloud.snapshot.records, normalizedId);
|
|
87
|
+
const references = cloud.snapshot.records.filter((record) => record.status === 'active' && record.type === 'reference');
|
|
88
|
+
const installed = await ports.materializeWorkspace({
|
|
89
|
+
...selected,
|
|
90
|
+
references,
|
|
91
|
+
destinationParent: destination,
|
|
92
|
+
cloudHead: required(cloud.checksum, 'cloud head'),
|
|
93
|
+
});
|
|
94
|
+
const installedRecords = (0, index_js_1.snapshotFromRecords)(installed.records || []).records;
|
|
95
|
+
if (!Number.isSafeInteger(installed.rows)
|
|
96
|
+
|| installed.rows !== installedRecords.length
|
|
97
|
+
|| !(0, index_js_1.sameRecords)((0, index_js_1.travelingRecords)(installedRecords), selected.records)
|
|
98
|
+
|| !(0, index_js_1.sameRecords)([installed.reference], [selected.reference])
|
|
99
|
+
|| !(0, index_js_1.sameRecords)(installed.references, references)) {
|
|
100
|
+
throw new Error('workspace materialization did not persist exactly the selected graph');
|
|
101
|
+
}
|
|
102
|
+
const coverage = await ports.coverWorkspace({
|
|
103
|
+
workspaceId: normalizedId,
|
|
104
|
+
baseline: installed.alreadyMaterialized === true ? 'existing' : 'authoritative-install',
|
|
105
|
+
});
|
|
106
|
+
if (coverage.active !== true || !Number.isSafeInteger(coverage.roots) || coverage.roots < 1) {
|
|
107
|
+
throw new Error('workspace watcher coverage is not active');
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
workspaceId: normalizedId,
|
|
111
|
+
workspaceName: selected.workspace.name,
|
|
112
|
+
path: required(installed.path, 'materialized workspace path'),
|
|
113
|
+
rows: installed.rows,
|
|
114
|
+
cloudHead: cloud.checksum,
|
|
115
|
+
materialized: true,
|
|
116
|
+
alreadyMaterialized: installed.alreadyMaterialized === true,
|
|
117
|
+
watcherRoots: coverage.roots,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/files/commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
/** Files product operations. Hosts own effects; Live owns decisions. */
|
|
18
|
+
__exportStar(require("./commands.js"), exports);
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/files/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,wEAAwE;AACxE,gDAA8B"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @amalgm/live — the portable realtime SDK for the Amalgm platform.
|
|
4
|
+
*
|
|
5
|
+
* Portable layers, one rule each:
|
|
6
|
+
*
|
|
7
|
+
* - `contracts/` every wire shape and identity rule, as types + validators
|
|
8
|
+
* - `machines/` the protocol's behavior, as pure state machines
|
|
9
|
+
* - `records/` the entity Record, local Outbox, authority, and Inbox laws
|
|
10
|
+
*
|
|
11
|
+
* Start at PURPOSE.md for the axioms; docs/ holds the normative specs.
|
|
12
|
+
*/
|
|
13
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
16
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
17
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
18
|
+
}
|
|
19
|
+
Object.defineProperty(o, k2, desc);
|
|
20
|
+
}) : (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
o[k2] = m[k];
|
|
23
|
+
}));
|
|
24
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
25
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
26
|
+
};
|
|
27
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28
|
+
__exportStar(require("./contracts/index.js"), exports);
|
|
29
|
+
__exportStar(require("./machines/index.js"), exports);
|
|
30
|
+
__exportStar(require("./entities/index.js"), exports);
|
|
31
|
+
__exportStar(require("./watching/index.js"), exports);
|
|
32
|
+
__exportStar(require("./detection/index.js"), exports);
|
|
33
|
+
__exportStar(require("./records/index.js"), exports);
|
|
34
|
+
__exportStar(require("./registration/index.js"), exports);
|
|
35
|
+
__exportStar(require("./files/index.js"), exports);
|
|
36
|
+
__exportStar(require("./transfer/index.js"), exports);
|
|
37
|
+
__exportStar(require("./merge/index.js"), exports);
|
|
38
|
+
__exportStar(require("./workspace/index.js"), exports);
|
|
39
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;;;;;;;;;;;;;;AAEH,uDAAqC;AACrC,sDAAoC;AACpC,sDAAoC;AACpC,sDAAoC;AACpC,uDAAqC;AACrC,qDAAmC;AACnC,0DAAwC;AACxC,mDAAiC;AACjC,sDAAoC;AACpC,mDAAiC;AACjC,uDAAqC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Tunnel slot arbitration — who owns `(computer_id, runtime_label)`.
|
|
4
|
+
*
|
|
5
|
+
* The gateway holds one slot per runtime identity; a newcomer's first
|
|
6
|
+
* identity-bearing hello decides the winner (local-live-protocol.md §5).
|
|
7
|
+
* This is the pure decision. The gateway supplies sockets and timers; the
|
|
8
|
+
* fencing rule — mark the loser superseded BEFORE closing it, drop its
|
|
9
|
+
* in-flight frames — is part of the contract and encoded in the verdict.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.ARBITRATION_DEADLINE_MS = void 0;
|
|
13
|
+
exports.decideSlot = decideSlot;
|
|
14
|
+
const tunnel_js_1 = require("../contracts/frames/tunnel.js");
|
|
15
|
+
/** A newcomer with a holder present buffers unrouted until its first identity-bearing hello, bounded by this deadline (AMALGM_TUNNEL_HELLO_ARBITRATION_MS). */
|
|
16
|
+
exports.ARBITRATION_DEADLINE_MS = 3_000;
|
|
17
|
+
/**
|
|
18
|
+
* Decide a contested slot.
|
|
19
|
+
*
|
|
20
|
+
* - same `instance_id` → newer socket wins (the same process reconnecting)
|
|
21
|
+
* - different `instance_id` → strictly newer `boot_ts` wins; older or EQUAL loses
|
|
22
|
+
* - unusable identity on either side (or the deadline expired — pass
|
|
23
|
+
* `holder: null` identity via `legacyFallback`) → last-connect-wins, logged as such by the caller
|
|
24
|
+
*/
|
|
25
|
+
function decideSlot(holder, newcomer) {
|
|
26
|
+
if (holder === null) {
|
|
27
|
+
return { install: true, fenceHolder: false, rule: 'free-slot' };
|
|
28
|
+
}
|
|
29
|
+
if (!(0, tunnel_js_1.hasUsableIdentity)(newcomer) || !(0, tunnel_js_1.hasUsableIdentity)(holder)) {
|
|
30
|
+
return { install: true, fenceHolder: true, rule: 'legacy-last-connect-wins' };
|
|
31
|
+
}
|
|
32
|
+
const contender = newcomer;
|
|
33
|
+
if (contender.instance_id === holder.instance_id) {
|
|
34
|
+
return { install: true, fenceHolder: true, rule: 'same-instance-reconnect' };
|
|
35
|
+
}
|
|
36
|
+
if (contender.boot_ts > holder.boot_ts) {
|
|
37
|
+
return { install: true, fenceHolder: true, rule: 'newer-boot' };
|
|
38
|
+
}
|
|
39
|
+
return { install: false, closeCode: tunnel_js_1.CLOSE_CODES.supersededInstance, rule: 'older-or-equal-boot' };
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=arbitration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arbitration.js","sourceRoot":"","sources":["../../src/machines/arbitration.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAuBH,gCAeC;AApCD,6DAAiG;AAEjG,+JAA+J;AAClJ,QAAA,uBAAuB,GAAG,KAAK,CAAC;AAU7C;;;;;;;GAOG;AACH,SAAgB,UAAU,CAAC,MAA2B,EAAE,QAA+B;IACrF,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IAClE,CAAC;IACD,IAAI,CAAC,IAAA,6BAAiB,EAAC,QAAQ,CAAC,IAAI,CAAC,IAAA,6BAAiB,EAAC,MAAM,CAAC,EAAE,CAAC;QAC/D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,0BAA0B,EAAE,CAAC;IAChF,CAAC;IACD,MAAM,SAAS,GAAG,QAAwB,CAAC;IAC3C,IAAI,SAAS,CAAC,WAAW,KAAK,MAAM,CAAC,WAAW,EAAE,CAAC;QACjD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,yBAAyB,EAAE,CAAC;IAC/E,CAAC;IACD,IAAI,SAAS,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;QACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;IAClE,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,uBAAW,CAAC,kBAAkB,EAAE,IAAI,EAAE,qBAAqB,EAAE,CAAC;AACpG,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Tunnel reconnect policy (local-live-protocol.md §5, runtime client
|
|
4
|
+
* behavior).
|
|
5
|
+
*
|
|
6
|
+
* Two rules keep a two-instance fight from becoming a reconnect war:
|
|
7
|
+
*
|
|
8
|
+
* 1. Exponential backoff resets to 1s only after a connection SURVIVED the
|
|
9
|
+
* stable window; a connection that dies younger keeps (and grows) the
|
|
10
|
+
* previous backoff.
|
|
11
|
+
* 2. A 4009 refusal ("superseded instance") retries after a fixed long
|
|
12
|
+
* delay — never a full stop, because a wrongly-refused instance must
|
|
13
|
+
* still recover once the true holder dies.
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.initialBackoff = exports.MAX_DELAY_MS = exports.BASE_DELAY_MS = exports.STABLE_RESET_MS = exports.SUPERSEDED_RETRY_MS = void 0;
|
|
17
|
+
exports.planReconnect = planReconnect;
|
|
18
|
+
const tunnel_js_1 = require("../contracts/frames/tunnel.js");
|
|
19
|
+
/** AMALGM_TUNNEL_SUPERSEDED_RETRY_MS */
|
|
20
|
+
exports.SUPERSEDED_RETRY_MS = 5 * 60_000;
|
|
21
|
+
/** AMALGM_TUNNEL_STABLE_RESET_MS — survival time that earns a reset to the base delay. */
|
|
22
|
+
exports.STABLE_RESET_MS = 30_000;
|
|
23
|
+
exports.BASE_DELAY_MS = 1_000;
|
|
24
|
+
exports.MAX_DELAY_MS = 60_000;
|
|
25
|
+
exports.initialBackoff = { delayMs: exports.BASE_DELAY_MS };
|
|
26
|
+
function planReconnect(state, disconnect) {
|
|
27
|
+
if (disconnect.closeCode === tunnel_js_1.CLOSE_CODES.supersededInstance) {
|
|
28
|
+
// Fixed, slow, and does not disturb the exponential state: an instance
|
|
29
|
+
// alternating between refusals and crashes must not launder its backoff.
|
|
30
|
+
return { waitMs: exports.SUPERSEDED_RETRY_MS, next: state, rule: 'superseded-fixed-retry' };
|
|
31
|
+
}
|
|
32
|
+
if (disconnect.connectedForMs >= exports.STABLE_RESET_MS) {
|
|
33
|
+
return { waitMs: exports.BASE_DELAY_MS, next: exports.initialBackoff, rule: 'stable-reset' };
|
|
34
|
+
}
|
|
35
|
+
const grown = Math.min(state.delayMs * 2, exports.MAX_DELAY_MS);
|
|
36
|
+
return { waitMs: state.delayMs, next: { delayMs: grown }, rule: 'exponential' };
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=backoff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backoff.js","sourceRoot":"","sources":["../../src/machines/backoff.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;;;AA8BH,sCAWC;AAvCD,6DAA4D;AAE5D,wCAAwC;AAC3B,QAAA,mBAAmB,GAAG,CAAC,GAAG,MAAM,CAAC;AAC9C,0FAA0F;AAC7E,QAAA,eAAe,GAAG,MAAM,CAAC;AACzB,QAAA,aAAa,GAAG,KAAK,CAAC;AACtB,QAAA,YAAY,GAAG,MAAM,CAAC;AAOtB,QAAA,cAAc,GAAiB,EAAE,OAAO,EAAE,qBAAa,EAAE,CAAC;AAcvE,SAAgB,aAAa,CAAC,KAAmB,EAAE,UAAsB;IACvE,IAAI,UAAU,CAAC,SAAS,KAAK,uBAAW,CAAC,kBAAkB,EAAE,CAAC;QAC5D,uEAAuE;QACvE,yEAAyE;QACzE,OAAO,EAAE,MAAM,EAAE,2BAAmB,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,wBAAwB,EAAE,CAAC;IACtF,CAAC;IACD,IAAI,UAAU,CAAC,cAAc,IAAI,uBAAe,EAAE,CAAC;QACjD,OAAO,EAAE,MAAM,EAAE,qBAAa,EAAE,IAAI,EAAE,sBAAc,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC;IAC/E,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,EAAE,oBAAY,CAAC,CAAC;IACxD,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;AAClF,CAAC"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The bootstrap machine — how a client reaches `live` truthfully.
|
|
4
|
+
*
|
|
5
|
+
* Ordered-bootstrap mode (local-live-protocol.md §3): the snapshot is the
|
|
6
|
+
* first data frame and everything after it is ordered on the same channel,
|
|
7
|
+
* so the machine simply installs and follows. Legacy mode: the snapshot
|
|
8
|
+
* travels out-of-band, so the machine holds events while the snapshot body
|
|
9
|
+
* is in flight and replays only those past its seq — the full-snapshot
|
|
10
|
+
* barrier (§6).
|
|
11
|
+
*
|
|
12
|
+
* Feature detection (§3): a bootstrap request against a legacy engine
|
|
13
|
+
* yields no `snapshot` frame. The client falls back to the legacy path
|
|
14
|
+
* when the first data frame is a `state` event, a `ping` arrives, or the
|
|
15
|
+
* timeout passes — whichever comes first.
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.SnapshotBarrier = exports.BootstrapMachine = void 0;
|
|
19
|
+
const stream_js_1 = require("../contracts/frames/stream.js");
|
|
20
|
+
/** One instance per bootstrap-mode connection attempt; discard after it resolves. */
|
|
21
|
+
class BootstrapMachine {
|
|
22
|
+
#held = [];
|
|
23
|
+
#resolved = false;
|
|
24
|
+
timeoutMs = stream_js_1.BOOTSTRAP_SNAPSHOT_TIMEOUT_MS;
|
|
25
|
+
/** Feed each stream frame until a command other than `none` resolves the machine. */
|
|
26
|
+
accept(frame) {
|
|
27
|
+
if (this.#resolved)
|
|
28
|
+
return { command: 'none' };
|
|
29
|
+
switch (frame.type) {
|
|
30
|
+
case 'snapshot': {
|
|
31
|
+
this.#resolved = true;
|
|
32
|
+
const snapshot = { seq: frame.seq, stable: frame.stable !== false, resources: frame.resources };
|
|
33
|
+
const replay = this.#held.filter((event) => event.seq > frame.seq);
|
|
34
|
+
this.#held = [];
|
|
35
|
+
return { command: 'install', snapshot, replay };
|
|
36
|
+
}
|
|
37
|
+
case 'state': {
|
|
38
|
+
if (this.#held.length === 0) {
|
|
39
|
+
// First data frame is an event, not a snapshot: legacy peer.
|
|
40
|
+
this.#resolved = true;
|
|
41
|
+
return { command: 'fallback-legacy', held: [frame.event], reason: 'state-before-snapshot' };
|
|
42
|
+
}
|
|
43
|
+
this.#held.push(frame.event);
|
|
44
|
+
return { command: 'none' };
|
|
45
|
+
}
|
|
46
|
+
case 'ping': {
|
|
47
|
+
this.#resolved = true;
|
|
48
|
+
const held = this.#held;
|
|
49
|
+
this.#held = [];
|
|
50
|
+
return { command: 'fallback-legacy', held, reason: 'ping-before-snapshot' };
|
|
51
|
+
}
|
|
52
|
+
case 'error': {
|
|
53
|
+
this.#resolved = true;
|
|
54
|
+
this.#held = [];
|
|
55
|
+
return frame.status === undefined ? { command: 'fallback-error' } : { command: 'fallback-error', status: frame.status };
|
|
56
|
+
}
|
|
57
|
+
case 'reset':
|
|
58
|
+
case 'presence':
|
|
59
|
+
return { command: 'none' };
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/** The host's timer fired without a snapshot frame. */
|
|
63
|
+
expire() {
|
|
64
|
+
if (this.#resolved)
|
|
65
|
+
return { command: 'none' };
|
|
66
|
+
this.#resolved = true;
|
|
67
|
+
const held = this.#held;
|
|
68
|
+
this.#held = [];
|
|
69
|
+
return { command: 'fallback-legacy', held, reason: 'timeout' };
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.BootstrapMachine = BootstrapMachine;
|
|
73
|
+
/**
|
|
74
|
+
* The legacy full-snapshot barrier (§6): hold events while a full snapshot
|
|
75
|
+
* body is in flight; on arrival, replay only those past its seq. Partial
|
|
76
|
+
* snapshots (resources added on a live connection) never pass through
|
|
77
|
+
* here — they hold per-resource and never bump the connection seq.
|
|
78
|
+
*/
|
|
79
|
+
class SnapshotBarrier {
|
|
80
|
+
#held = [];
|
|
81
|
+
#inFlight = false;
|
|
82
|
+
get inFlight() {
|
|
83
|
+
return this.#inFlight;
|
|
84
|
+
}
|
|
85
|
+
begin() {
|
|
86
|
+
this.#inFlight = true;
|
|
87
|
+
this.#held = [];
|
|
88
|
+
}
|
|
89
|
+
/** Returns true when the event was held (a snapshot body is in flight). */
|
|
90
|
+
hold(event) {
|
|
91
|
+
if (!this.#inFlight)
|
|
92
|
+
return false;
|
|
93
|
+
this.#held.push(event);
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
/** The snapshot body landed: install it, then apply the returned events in order. */
|
|
97
|
+
complete(snapshot) {
|
|
98
|
+
this.#inFlight = false;
|
|
99
|
+
const replay = this.#held.filter((event) => event.seq > snapshot.seq).sort((a, b) => a.seq - b.seq);
|
|
100
|
+
this.#held = [];
|
|
101
|
+
return replay;
|
|
102
|
+
}
|
|
103
|
+
/** The snapshot fetch failed: release nothing; the caller re-syncs. */
|
|
104
|
+
abandon() {
|
|
105
|
+
this.#inFlight = false;
|
|
106
|
+
this.#held = [];
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
exports.SnapshotBarrier = SnapshotBarrier;
|
|
110
|
+
//# sourceMappingURL=bootstrap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/machines/bootstrap.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Chunked response reassembly — the receiving half of §5's
|
|
4
|
+
* res_start / res_chunk / res_end train.
|
|
5
|
+
*
|
|
6
|
+
* Chunks reassemble by concatenating in index order; `res_end.chunks` must
|
|
7
|
+
* match the count received, else the whole response is treated as a 502
|
|
8
|
+
* for that request. Control frames interleaving between chunks is the
|
|
9
|
+
* feature, so the assembler tolerates any arrival interleaving across
|
|
10
|
+
* requests — but never within one (indexes must arrive 0,1,2,…).
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.ChunkAssembler = void 0;
|
|
14
|
+
exports.planChunks = planChunks;
|
|
15
|
+
/**
|
|
16
|
+
* One assembler per tunnel connection. The host must call `abandon` when a
|
|
17
|
+
* request times out — the accumulator is memory, and §5 requires cleanup
|
|
18
|
+
* on the request timeout (AMALGM_TUNNEL_REQUEST_TIMEOUT_MS).
|
|
19
|
+
*/
|
|
20
|
+
class ChunkAssembler {
|
|
21
|
+
#pending = new Map();
|
|
22
|
+
/** In-flight accumulator count, exposed for diagnostics (§5 getTunnelDebugStats). */
|
|
23
|
+
get pending() {
|
|
24
|
+
return this.#pending.size;
|
|
25
|
+
}
|
|
26
|
+
accept(frame) {
|
|
27
|
+
switch (frame.type) {
|
|
28
|
+
case 'res_start': {
|
|
29
|
+
this.#pending.set(frame.req_id, { status: frame.status, headers: frame.headers, chunks: [] });
|
|
30
|
+
return { done: false };
|
|
31
|
+
}
|
|
32
|
+
case 'res_chunk': {
|
|
33
|
+
const acc = this.#pending.get(frame.req_id);
|
|
34
|
+
if (!acc)
|
|
35
|
+
return { done: true, error: `res_chunk for unknown req_id ${frame.req_id}` };
|
|
36
|
+
if (frame.index !== acc.chunks.length) {
|
|
37
|
+
this.#pending.delete(frame.req_id);
|
|
38
|
+
return { done: true, error: `res_chunk index ${frame.index} arrived out of order (expected ${acc.chunks.length})` };
|
|
39
|
+
}
|
|
40
|
+
acc.chunks.push(frame.body_b64);
|
|
41
|
+
return { done: false };
|
|
42
|
+
}
|
|
43
|
+
case 'res_end': {
|
|
44
|
+
const acc = this.#pending.get(frame.req_id);
|
|
45
|
+
this.#pending.delete(frame.req_id);
|
|
46
|
+
if (!acc)
|
|
47
|
+
return { done: true, error: `res_end for unknown req_id ${frame.req_id}` };
|
|
48
|
+
if (frame.chunks !== acc.chunks.length) {
|
|
49
|
+
return { done: true, error: `res_end declared ${frame.chunks} chunks but ${acc.chunks.length} arrived` };
|
|
50
|
+
}
|
|
51
|
+
return { done: true, response: { status: acc.status, headers: acc.headers, bodyChunksB64: acc.chunks } };
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/** Drop a timed-out request's accumulator. Returns whether one existed. */
|
|
56
|
+
abandon(reqId) {
|
|
57
|
+
return this.#pending.delete(reqId);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.ChunkAssembler = ChunkAssembler;
|
|
61
|
+
/**
|
|
62
|
+
* Sender-side chunk plan for a raw body size: how many chunks a v2 peer
|
|
63
|
+
* will receive. The budget check happens BEFORE materializing any frame
|
|
64
|
+
* (§5): an over-budget response is dropped as a 503 without ever building
|
|
65
|
+
* its chunks — hence the plan is sizes only, never buffers.
|
|
66
|
+
*/
|
|
67
|
+
function planChunks(bodyBytes, chunkMaxBytes) {
|
|
68
|
+
if (bodyBytes < 0 || !Number.isSafeInteger(bodyBytes))
|
|
69
|
+
return { chunks: 0 };
|
|
70
|
+
return { chunks: bodyBytes === 0 ? 1 : Math.ceil(bodyBytes / chunkMaxBytes) };
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=chunks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunks.js","sourceRoot":"","sources":["../../src/machines/chunks.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;AA4EH,gCAGC;AAxDD;;;;GAIG;AACH,MAAa,cAAc;IACzB,QAAQ,GAAG,IAAI,GAAG,EAAuB,CAAC;IAE1C,qFAAqF;IACrF,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC5B,CAAC;IAED,MAAM,CAAC,KAA2B;QAChC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,WAAW,CAAC,CAAC,CAAC;gBACjB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;gBAC9F,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;YACzB,CAAC;YACD,KAAK,WAAW,CAAC,CAAC,CAAC;gBACjB,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBAC5C,IAAI,CAAC,GAAG;oBAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,gCAAgC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;gBACvF,IAAI,KAAK,CAAC,KAAK,KAAK,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;oBACtC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;oBACnC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,mBAAmB,KAAK,CAAC,KAAK,mCAAmC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,EAAE,CAAC;gBACtH,CAAC;gBACD,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBAChC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;YACzB,CAAC;YACD,KAAK,SAAS,CAAC,CAAC,CAAC;gBACf,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBAC5C,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBACnC,IAAI,CAAC,GAAG;oBAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,8BAA8B,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;gBACrF,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;oBACvC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,oBAAoB,KAAK,CAAC,MAAM,eAAe,GAAG,CAAC,MAAM,CAAC,MAAM,UAAU,EAAE,CAAC;gBAC3G,CAAC;gBACD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC;YAC3G,CAAC;QACH,CAAC;IACH,CAAC;IAED,2EAA2E;IAC3E,OAAO,CAAC,KAAa;QACnB,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC;CACF;AAxCD,wCAwCC;AAED;;;;;GAKG;AACH,SAAgB,UAAU,CAAC,SAAiB,EAAE,aAAqB;IACjE,IAAI,SAAS,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IAC5E,OAAO,EAAE,MAAM,EAAE,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,aAAa,CAAC,EAAE,CAAC;AAChF,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The machines layer: the protocol's behavior as pure, deterministic state
|
|
4
|
+
* machines. Every machine takes wire shapes in and returns decisions as
|
|
5
|
+
* data — the host performs the fetches, timers, and writes. Nothing in
|
|
6
|
+
* here opens a socket, reads a clock, or touches a disk.
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
20
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
21
|
+
};
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
__exportStar(require("./bootstrap.js"), exports);
|
|
24
|
+
__exportStar(require("./presence.js"), exports);
|
|
25
|
+
__exportStar(require("./arbitration.js"), exports);
|
|
26
|
+
__exportStar(require("./chunks.js"), exports);
|
|
27
|
+
__exportStar(require("./backoff.js"), exports);
|
|
28
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/machines/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;;;;;;;;;;;;AAEH,iDAA+B;AAC/B,gDAA8B;AAC9B,mDAAiC;AACjC,8CAA4B;AAC5B,+CAA6B"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Presence receiver — arrival-clock TTL over replace-not-merge frames.
|
|
4
|
+
*
|
|
5
|
+
* A presence frame carries the FULL peer list for one resource; receivers
|
|
6
|
+
* replace their view and treat absence as the default that publishing
|
|
7
|
+
* re-earns (local-live-protocol.md §2). The server already expires stale
|
|
8
|
+
* publishers, but receivers must apply their OWN arrival-clock TTL — a
|
|
9
|
+
* frozen stream must not preserve ghosts.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.PresenceView = void 0;
|
|
13
|
+
const presence_js_1 = require("../contracts/presence.js");
|
|
14
|
+
class PresenceView {
|
|
15
|
+
ttlMs;
|
|
16
|
+
#byResource = new Map();
|
|
17
|
+
constructor(ttlMs = presence_js_1.SERVER_TTL_MS) {
|
|
18
|
+
this.ttlMs = ttlMs;
|
|
19
|
+
}
|
|
20
|
+
/** Replace one resource's peer view. `nowMs` is the receiver's clock (host-supplied — the SDK holds no clock). */
|
|
21
|
+
accept(frame, nowMs) {
|
|
22
|
+
const peers = new Map();
|
|
23
|
+
for (const peer of frame.peers) {
|
|
24
|
+
peers.set(peer.session, { ...peer, arrivedAtMs: nowMs });
|
|
25
|
+
}
|
|
26
|
+
if (peers.size === 0)
|
|
27
|
+
this.#byResource.delete(frame.resource);
|
|
28
|
+
else
|
|
29
|
+
this.#byResource.set(frame.resource, peers);
|
|
30
|
+
}
|
|
31
|
+
/** Live peers for a resource, with expired entries dropped as of `nowMs`. */
|
|
32
|
+
peers(resource, nowMs) {
|
|
33
|
+
const peers = this.#byResource.get(resource);
|
|
34
|
+
if (!peers)
|
|
35
|
+
return [];
|
|
36
|
+
const alive = [];
|
|
37
|
+
for (const [session, peer] of peers) {
|
|
38
|
+
if (nowMs - peer.arrivedAtMs > this.ttlMs)
|
|
39
|
+
peers.delete(session);
|
|
40
|
+
else
|
|
41
|
+
alive.push(peer);
|
|
42
|
+
}
|
|
43
|
+
if (peers.size === 0)
|
|
44
|
+
this.#byResource.delete(resource);
|
|
45
|
+
return alive;
|
|
46
|
+
}
|
|
47
|
+
/** Delivery was lost: presence is not replayed after a gap, so the view must not outlive its stream. */
|
|
48
|
+
clear() {
|
|
49
|
+
this.#byResource.clear();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.PresenceView = PresenceView;
|
|
53
|
+
//# sourceMappingURL=presence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presence.js","sourceRoot":"","sources":["../../src/machines/presence.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAEH,0DAAgG;AAOhG,MAAa,YAAY;IAGM;IAF7B,WAAW,GAAG,IAAI,GAAG,EAAiC,CAAC;IAEvD,YAA6B,QAAgB,2BAAa;QAA7B,UAAK,GAAL,KAAK,CAAwB;IAAG,CAAC;IAE9D,kHAAkH;IAClH,MAAM,CAAC,KAAoB,EAAE,KAAa;QACxC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAoB,CAAC;QAC1C,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAC/B,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,GAAG,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC;QAC3D,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC;YAAE,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;;YACzD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACnD,CAAC;IAED,6EAA6E;IAC7E,KAAK,CAAC,QAAgB,EAAE,KAAa;QACnC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7C,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,CAAC;QACtB,MAAM,KAAK,GAAe,EAAE,CAAC;QAC7B,KAAK,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,KAAK,EAAE,CAAC;YACpC,IAAI,KAAK,GAAG,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK;gBAAE,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;;gBAC5D,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxB,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC;YAAE,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACxD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,wGAAwG;IACxG,KAAK;QACH,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;IAC3B,CAAC;CACF;AAhCD,oCAgCC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The merge layer: the text-reconciliation engine behind live documents.
|
|
4
|
+
* `merge3` is the diff3 core; the doc-write decision policy
|
|
5
|
+
* (`decideDocWrite` — outcome selection, retention-ring base resolution,
|
|
6
|
+
* overwrite-deletes-text) joins it here as the next extraction slice
|
|
7
|
+
* (ROADMAP.md #1).
|
|
8
|
+
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
21
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
22
|
+
};
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
__exportStar(require("./merge3.js"), exports);
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/merge/index.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;;;;;;;;;;;;;;AAEH,8CAA4B"}
|