@astrosheep/square 0.3.70 → 0.3.72
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/dist/activity-feed.d.ts +4 -5
- package/dist/activity-feed.js +14 -10
- package/dist/artifact.d.ts +26 -33
- package/dist/artifact.js +346 -317
- package/dist/attention-presentation.js +2 -9
- package/dist/automatic-session.js +6 -6
- package/dist/boundary-presentation.js +3 -3
- package/dist/catch-decisions.d.ts +19 -12
- package/dist/catch-decisions.js +32 -68
- package/dist/claude-delivery.js +7 -7
- package/dist/claude-mod.js +18 -7
- package/dist/cli/catch-presentation.d.ts +7 -0
- package/dist/cli/catch-presentation.js +55 -0
- package/dist/cli/context.d.ts +1 -1
- package/dist/cli/context.js +5 -23
- package/dist/cli/express-presentation.d.ts +10 -0
- package/dist/cli/express-presentation.js +196 -0
- package/dist/cli/maintenance-commands.d.ts +4 -0
- package/dist/cli/maintenance-commands.js +29 -6
- package/dist/cli/observation-commands.d.ts +7 -5
- package/dist/cli/observation-commands.js +275 -262
- package/dist/cli/program.d.ts +1 -1
- package/dist/cli/program.js +43 -56
- package/dist/cli/registry.js +2 -1
- package/dist/cli/square-commands.d.ts +3 -9
- package/dist/cli/square-commands.js +134 -255
- package/dist/codex-queue.js +4 -1
- package/dist/decisions.d.ts +26 -74
- package/dist/decisions.js +190 -335
- package/dist/delivery-health.js +13 -22
- package/dist/delivery-operations.d.ts +0 -11
- package/dist/delivery-operations.js +44 -33
- package/dist/delivery.d.ts +33 -32
- package/dist/delivery.js +70 -81
- package/dist/help.js +6 -1
- package/dist/inbox.d.ts +27 -0
- package/dist/inbox.js +55 -18
- package/dist/index.d.ts +2 -4
- package/dist/index.js +1 -1
- package/dist/list.d.ts +7 -1
- package/dist/list.js +49 -122
- package/dist/mcp.d.ts +1 -1
- package/dist/mcp.js +7 -37
- package/dist/model.d.ts +4 -44
- package/dist/model.js +1 -3
- package/dist/notifications.d.ts +1 -1
- package/dist/notifications.js +13 -7
- package/dist/open-square.d.ts +16 -2
- package/dist/open-square.js +40 -1
- package/dist/packages/agent-delivery/src/claude.d.ts +2 -11
- package/dist/packages/agent-delivery/src/index.d.ts +2 -42
- package/dist/packages/agent-delivery/src/opencode.d.ts +2 -11
- package/dist/packages/agent-delivery/src/paseo.d.ts +2 -13
- package/dist/packages/agent-delivery/src/pi-client.d.ts +2 -9
- package/dist/packages/agent-delivery/src/types.d.ts +42 -0
- package/dist/participant-host.d.ts +6 -3
- package/dist/participant-host.js +44 -38
- package/dist/perception-projection.d.ts +6 -15
- package/dist/perception-projection.js +6 -26
- package/dist/plugins/opencode/delivery.js +9 -9
- package/dist/plugins/opencode/index.js +3 -3
- package/dist/ports.d.ts +156 -11
- package/dist/presentation-operations.d.ts +1 -1
- package/dist/presentation-operations.js +35 -44
- package/dist/presentation.d.ts +12 -19
- package/dist/presentation.js +33 -54
- package/dist/registry.d.ts +2 -0
- package/dist/registry.js +1 -1
- package/dist/routes.d.ts +7 -14
- package/dist/routes.js +34 -72
- package/dist/runtime.d.ts +12 -39
- package/dist/runtime.js +33 -164
- package/dist/square-actions.d.ts +11 -21
- package/dist/square-actions.js +171 -275
- package/dist/square-application.d.ts +31 -55
- package/dist/square-application.js +625 -141
- package/dist/square-core.d.ts +3 -94
- package/dist/square-core.js +8 -353
- package/dist/square-domain.d.ts +24 -0
- package/dist/square-domain.js +77 -0
- package/dist/square-facade.d.ts +360 -9
- package/dist/square-migration.d.ts +24 -0
- package/dist/square-migration.js +211 -0
- package/dist/square-projections.d.ts +2 -42
- package/dist/square-projections.js +1 -37
- package/dist/square-sqlite.d.ts +59 -0
- package/dist/square-sqlite.js +702 -0
- package/dist/stream.d.ts +3 -10
- package/dist/stream.js +81 -52
- package/dist/views.d.ts +27 -95
- package/dist/views.js +217 -87
- package/dist/wake-eligibility.d.ts +15 -5
- package/dist/wake-eligibility.js +32 -16
- package/dist/wakes.d.ts +3 -3
- package/dist/wakes.js +31 -27
- package/guides/application-facade-delivery-evidence.md +200 -0
- package/guides/application-facade-design.md +95 -0
- package/guides/change-waits.md +4 -4
- package/guides/migration.md +77 -0
- package/guides/postcommit-simplification-performance.md +36 -0
- package/guides/primitive-catch-consolidation.md +85 -0
- package/guides/primitive-history-consolidation.md +76 -0
- package/guides/primitive-status-consolidation.md +87 -0
- package/guides/primitive-storage-consolidation.md +128 -0
- package/guides/row-runtime-delivery-evidence.md +160 -0
- package/guides/row-storage-design.md +567 -0
- package/package.json +1 -1
- package/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/plugins/codex/.codex-plugin/plugin.json +1 -1
- package/plugins/opencode/delivery.ts +11 -11
- package/plugins/opencode/index.ts +3 -3
- package/plugins/paseo/client/square-message.tsx +77 -64
- package/plugins/paseo/shared/message.ts +16 -0
- package/plugins/pi/square-pi.js +5 -1
- package/dist/activity.d.ts +0 -14
- package/dist/activity.js +0 -248
- package/dist/square-file-adapter.d.ts +0 -26
- package/dist/square-file-adapter.js +0 -85
- package/dist/square-state.d.ts +0 -6
- package/dist/square-state.js +0 -138
- package/dist/square-storage.d.ts +0 -14
- package/dist/square-storage.js +0 -188
- package/dist/square-wiring.d.ts +0 -33
- package/dist/square-wiring.js +0 -109
- package/dist/watch.d.ts +0 -8
- package/dist/watch.js +0 -252
package/dist/runtime.d.ts
CHANGED
|
@@ -1,48 +1,21 @@
|
|
|
1
|
-
import { type ActivityId
|
|
2
|
-
import { type StoredAct, type
|
|
1
|
+
import { type ActivityId } from './square-core.js';
|
|
2
|
+
import { type StoredAct, type WatchLease } from './model.js';
|
|
3
|
+
import type { SquareRead } from './ports.js';
|
|
3
4
|
export declare const WATCH_HEARTBEAT_MS: number;
|
|
4
5
|
export declare const SLEEP_MS: number;
|
|
5
6
|
export declare const STALE_MS: number;
|
|
6
7
|
export declare const WATCH_STALE_MS: number;
|
|
7
8
|
export declare const THROTTLE_WINDOW_MS: number;
|
|
8
9
|
export declare const UNREAD_BLOCK_GRACE_MS: number;
|
|
9
|
-
/** A held express waits for the hand to lower, but not forever: past this budget it gives up exactly like --no-wait (draft saved, retry printed). 0 disables waiting. */
|
|
10
10
|
export declare const HELD_WAIT_BUDGET_MS: number;
|
|
11
|
+
export declare const FACT_PAGE_SIZE = 100;
|
|
11
12
|
export declare function nowMs(): number;
|
|
12
|
-
|
|
13
|
-
export declare function
|
|
14
|
-
body: string;
|
|
15
|
-
mentions?: readonly string[];
|
|
16
|
-
reach?: Reach;
|
|
17
|
-
}, mention: string | true): boolean;
|
|
18
|
-
export declare function foldedState(squareState: SquareState): import("./square-core.js").FoldedSquareState;
|
|
19
|
-
export declare function rosterNames(squareState: SquareState): string[];
|
|
20
|
-
export declare function inSquareCount(squareState: SquareState): number;
|
|
21
|
-
export declare function resolveRosterName(squareState: SquareState, name: string): string | undefined;
|
|
22
|
-
export declare function countSays(acts: StoredAct[], name: string): number;
|
|
23
|
-
export declare function sayNumberFor(acts: StoredAct[], target: StoredAct): number;
|
|
24
|
-
/** Shared terminal condition for a participant's watch lifecycle. */
|
|
25
|
-
export declare function watchTerminalStatus(squareState: SquareState, name: string): 'capped' | 'quorum' | undefined;
|
|
26
|
-
export declare function joinedNames(acts: StoredAct[]): Set<string>;
|
|
27
|
-
export declare function isCurrentlyJoined(acts: StoredAct[], name: string): boolean;
|
|
28
|
-
/** Stable index of the recipient's most recent join act, if any. */
|
|
29
|
-
export declare function lastJoinIndex(acts: StoredAct[], name: string): number | undefined;
|
|
30
|
-
export declare function actStableIndex(act: StoredAct): number;
|
|
13
|
+
export declare function rosterNames(facts: SquareRead): string[];
|
|
14
|
+
export declare function inSquareCount(facts: SquareRead): number;
|
|
31
15
|
export declare function actId(actOrIndex: StoredAct | number): ActivityId;
|
|
32
|
-
export declare function
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
export declare function
|
|
37
|
-
export declare function
|
|
38
|
-
/**
|
|
39
|
-
* The last public act the participant was verifiably present for, or -1 when there is no evidence.
|
|
40
|
-
*
|
|
41
|
-
* "Was here" is a claim of presence, so it rides on evidence: the participant's own acts
|
|
42
|
-
* and seen receipts after their latest join. Anything else — in particular acts merely
|
|
43
|
-
* not addressed to them — says nothing about where they actually were.
|
|
44
|
-
*/
|
|
45
|
-
export declare function presenceAnchor(squareState: SquareState, name: string, landed?: LandedAudienceReplay): number;
|
|
46
|
-
export declare function freshWatchLease(squareState: SquareState, name: string, at?: number): WatchLease | undefined;
|
|
47
|
-
export declare function writeWatchLease(squareState: SquareState, name: string, lease: WatchLease): void;
|
|
48
|
-
export declare function removeWatchLease(squareState: SquareState, name: string, leaseId: string): boolean;
|
|
16
|
+
export declare function watchTerminalStatus(facts: SquareRead, name: string): 'capped' | 'quorum' | undefined;
|
|
17
|
+
/** A continuous prefix stops at the first unseen historical audience edge after join. */
|
|
18
|
+
export declare function readCursor(facts: SquareRead, name: string): number;
|
|
19
|
+
/** Presence rides on own activity or exact receipts, not nonaddressed cursor progress. */
|
|
20
|
+
export declare function presenceAnchor(facts: SquareRead, name: string): number;
|
|
21
|
+
export declare function freshWatchLease(facts: SquareRead, name: string, at?: number): WatchLease | undefined;
|
package/dist/runtime.js
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { SquareError,
|
|
1
|
+
import { formatActivityId } from './square-core.js';
|
|
2
|
+
import { SquareError, sameName } from './model.js';
|
|
3
3
|
function parseIntegerEnv(name, fallback) {
|
|
4
4
|
const raw = process.env[name];
|
|
5
5
|
if (raw === undefined)
|
|
6
6
|
return fallback;
|
|
7
7
|
const value = parseInt(raw, 10);
|
|
8
|
-
if (!Number.isFinite(value) || value <= 0)
|
|
8
|
+
if (!Number.isFinite(value) || value <= 0)
|
|
9
9
|
throw new SquareError('invalid_args', `Invalid ${name}: expected a positive integer.`);
|
|
10
|
-
}
|
|
11
10
|
return value;
|
|
12
11
|
}
|
|
13
12
|
export const WATCH_HEARTBEAT_MS = parseIntegerEnv('SQUARE_WATCH_HEARTBEAT_MS', 60000);
|
|
@@ -16,177 +15,47 @@ export const STALE_MS = parseIntegerEnv('SQUARE_WATCH_QUIET_MS', 300000);
|
|
|
16
15
|
export const WATCH_STALE_MS = parseIntegerEnv('SQUARE_WATCH_STALE_MS', 180000);
|
|
17
16
|
export const THROTTLE_WINDOW_MS = parseIntegerEnv('SQUARE_THROTTLE_WINDOW_MS', 60000);
|
|
18
17
|
export const UNREAD_BLOCK_GRACE_MS = parseIntegerEnv('SQUARE_UNREAD_BLOCK_GRACE_MS', 90000);
|
|
19
|
-
/** A held express waits for the hand to lower, but not forever: past this budget it gives up exactly like --no-wait (draft saved, retry printed). 0 disables waiting. */
|
|
20
18
|
export const HELD_WAIT_BUDGET_MS = parseIntegerEnv('SQUARE_HELD_WAIT_BUDGET_MS', 10 * 60 * 1000);
|
|
19
|
+
export const FACT_PAGE_SIZE = 100;
|
|
21
20
|
export function nowMs() {
|
|
22
21
|
const override = process.env.SQUARE_NOW_MS;
|
|
23
22
|
if (override === undefined)
|
|
24
23
|
return Date.now();
|
|
25
24
|
const value = parseInt(override, 10);
|
|
26
|
-
if (!Number.isFinite(value))
|
|
25
|
+
if (!Number.isFinite(value))
|
|
27
26
|
throw new SquareError('invalid_args', 'Invalid SQUARE_NOW_MS: expected integer milliseconds.');
|
|
28
|
-
}
|
|
29
27
|
return value;
|
|
30
28
|
}
|
|
31
|
-
|
|
32
|
-
export function
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
export function foldedState(squareState) {
|
|
39
|
-
return fold(squareState.acts);
|
|
40
|
-
}
|
|
41
|
-
export function rosterNames(squareState) {
|
|
42
|
-
return foldedState(squareState).participants.map((participant) => participant.name);
|
|
43
|
-
}
|
|
44
|
-
export function inSquareCount(squareState) {
|
|
45
|
-
return foldedState(squareState).joined.length;
|
|
46
|
-
}
|
|
47
|
-
export function resolveRosterName(squareState, name) {
|
|
48
|
-
return findParticipantName(rosterNames(squareState), name);
|
|
49
|
-
}
|
|
50
|
-
export function countSays(acts, name) {
|
|
51
|
-
return acts.filter((act) => act.kind === 'say' && sameName(act.actor, name)).length;
|
|
52
|
-
}
|
|
53
|
-
export function sayNumberFor(acts, target) {
|
|
54
|
-
if (target.kind !== 'say')
|
|
55
|
-
throw new Error('sayNumberFor only applies to say acts');
|
|
56
|
-
let number = 0;
|
|
57
|
-
for (const act of acts) {
|
|
58
|
-
if (act.kind === 'say' && sameName(act.actor, target.actor))
|
|
59
|
-
number++;
|
|
60
|
-
if (act === target)
|
|
61
|
-
return number;
|
|
62
|
-
if (target.index !== undefined && act.index === target.index)
|
|
63
|
-
return number;
|
|
64
|
-
}
|
|
65
|
-
throw new Error('target say act is not present in act history');
|
|
66
|
-
}
|
|
67
|
-
/** Shared terminal condition for a participant's watch lifecycle. */
|
|
68
|
-
export function watchTerminalStatus(squareState, name) {
|
|
69
|
-
if (squareState.hardCap !== null && countSays(squareState.acts, name) >= squareState.hardCap)
|
|
29
|
+
export function rosterNames(facts) { return facts.roster().map((participant) => participant.name); }
|
|
30
|
+
export function inSquareCount(facts) { return facts.roster().filter((participant) => participant.joined).length; }
|
|
31
|
+
export function actId(actOrIndex) { return formatActivityId(typeof actOrIndex === 'number' ? actOrIndex : actOrIndex.index); }
|
|
32
|
+
export function watchTerminalStatus(facts, name) {
|
|
33
|
+
const cap = facts.header().hardCap;
|
|
34
|
+
if (cap !== null && (facts.participant(name)?.sayCount ?? 0) >= cap)
|
|
70
35
|
return 'capped';
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
last = actStableIndex(act);
|
|
88
|
-
}
|
|
89
|
-
return last;
|
|
90
|
-
}
|
|
91
|
-
export function actStableIndex(act) {
|
|
92
|
-
if (act.index === undefined)
|
|
93
|
-
throw new Error(`act ${act.kind} is missing a stable index`);
|
|
94
|
-
return act.index;
|
|
95
|
-
}
|
|
96
|
-
export function actId(actOrIndex) {
|
|
97
|
-
const index = typeof actOrIndex === 'number' ? actOrIndex : actStableIndex(actOrIndex);
|
|
98
|
-
return formatActivityId(index);
|
|
99
|
-
}
|
|
100
|
-
function canonicalRuntimeName(squareState, name) {
|
|
101
|
-
return resolveRosterName(squareState, name) ?? name;
|
|
102
|
-
}
|
|
103
|
-
export function currentHold(acts) {
|
|
104
|
-
const hold = fold(acts).hold;
|
|
105
|
-
return hold.active ? { active: true, at: hold.at, reason: hold.reason } : { active: false };
|
|
106
|
-
}
|
|
107
|
-
export function publicActs(acts) {
|
|
108
|
-
return acts.filter((act) => act.kind === 'say' || act.kind === 'done');
|
|
109
|
-
}
|
|
110
|
-
export function recordObservation(squareState, name, index, state, at = Date.now()) {
|
|
111
|
-
if (!Number.isSafeInteger(index) || index < 0 || !Number.isFinite(at))
|
|
112
|
-
return false;
|
|
113
|
-
const key = canonicalRuntimeName(squareState, name);
|
|
114
|
-
const id = formatActivityId(index);
|
|
115
|
-
const current = squareState.runtime.observations[key]?.[id];
|
|
116
|
-
if (current?.state === 'seen' || (current?.state === state && current.at >= at))
|
|
117
|
-
return false;
|
|
118
|
-
const next = {
|
|
119
|
-
state: 'seen',
|
|
120
|
-
at: Math.max(current?.at ?? -Infinity, at),
|
|
121
|
-
};
|
|
122
|
-
((squareState.runtime.observations ??= {})[key] ??= {})[id] = next;
|
|
123
|
-
return true;
|
|
124
|
-
}
|
|
125
|
-
export function readCursor(squareState, name, landed = replayLandedAudiences(squareState.acts)) {
|
|
126
|
-
const recipient = landed.resolveParticipant(name) ?? name;
|
|
127
|
-
const boundary = landed.lastJoinIndex(recipient) ?? -1;
|
|
128
|
-
let cursor = boundary;
|
|
129
|
-
for (const act of squareState.acts) {
|
|
130
|
-
if (act.index <= boundary || act.kind === 'read' || act.actor === undefined)
|
|
131
|
-
continue;
|
|
132
|
-
if (sameName(act.actor, recipient)) {
|
|
133
|
-
cursor = act.index;
|
|
134
|
-
continue;
|
|
135
|
-
}
|
|
136
|
-
if (!landed.includes(act, recipient)) {
|
|
137
|
-
cursor = act.index;
|
|
138
|
-
continue;
|
|
139
|
-
}
|
|
140
|
-
if (squareState.runtime.observations?.[recipient]?.[formatActivityId(act.index)]?.state !== 'seen')
|
|
141
|
-
break;
|
|
142
|
-
cursor = act.index;
|
|
143
|
-
}
|
|
144
|
-
return cursor;
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* The last public act the participant was verifiably present for, or -1 when there is no evidence.
|
|
148
|
-
*
|
|
149
|
-
* "Was here" is a claim of presence, so it rides on evidence: the participant's own acts
|
|
150
|
-
* and seen receipts after their latest join. Anything else — in particular acts merely
|
|
151
|
-
* not addressed to them — says nothing about where they actually were.
|
|
152
|
-
*/
|
|
153
|
-
export function presenceAnchor(squareState, name, landed = replayLandedAudiences(squareState.acts)) {
|
|
154
|
-
const recipient = landed.resolveParticipant(name) ?? name;
|
|
155
|
-
const boundary = landed.lastJoinIndex(recipient) ?? -1;
|
|
36
|
+
const peers = facts.roster().filter((participant) => !sameName(participant.name, name));
|
|
37
|
+
return peers.length > 0 && peers.every((peer) => peer.done) ? 'quorum' : undefined;
|
|
38
|
+
}
|
|
39
|
+
/** A continuous prefix stops at the first unseen historical audience edge after join. */
|
|
40
|
+
export function readCursor(facts, name) {
|
|
41
|
+
const boundary = facts.participant(name)?.lastJoinIndex ?? -1;
|
|
42
|
+
const block = facts.directed(name, { afterIndex: boundary, unseenOnly: true }, { edge: 'oldest', limit: 1 }).items[0]?.index;
|
|
43
|
+
const last = facts.activityHeads({
|
|
44
|
+
afterIndex: boundary, ...(block === undefined ? {} : { beforeIndex: block }), actorRequired: true,
|
|
45
|
+
kinds: ['join', 'done', 'say', 'hold', 'resume', 'listen', 'ignore'],
|
|
46
|
+
}, { edge: 'newest', limit: 1 }).items[0]?.index;
|
|
47
|
+
return Math.max(boundary, last ?? boundary);
|
|
48
|
+
}
|
|
49
|
+
/** Presence rides on own activity or exact receipts, not nonaddressed cursor progress. */
|
|
50
|
+
export function presenceAnchor(facts, name) {
|
|
51
|
+
const boundary = facts.participant(name)?.lastJoinIndex ?? -1;
|
|
156
52
|
if (boundary < 0)
|
|
157
53
|
return -1;
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
continue;
|
|
162
|
-
if (sameName(act.actor, recipient)
|
|
163
|
-
|| squareState.runtime.observations?.[recipient]?.[formatActivityId(act.index)]?.state === 'seen') {
|
|
164
|
-
evidence = act.index;
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
for (let i = squareState.acts.length - 1; i >= 0; i--) {
|
|
168
|
-
const event = squareState.acts[i];
|
|
169
|
-
if (event.index <= boundary || event.index > evidence)
|
|
170
|
-
continue;
|
|
171
|
-
if (event.kind === 'say' || event.kind === 'done')
|
|
172
|
-
return event.index;
|
|
173
|
-
}
|
|
174
|
-
return -1;
|
|
175
|
-
}
|
|
176
|
-
export function freshWatchLease(squareState, name, at = Date.now()) {
|
|
177
|
-
const key = canonicalRuntimeName(squareState, name);
|
|
178
|
-
const lease = squareState.runtime.leases[key];
|
|
179
|
-
if (lease === undefined || lease.expiresAt <= at || at - lease.heartbeatAt > WATCH_STALE_MS)
|
|
180
|
-
return undefined;
|
|
181
|
-
return lease;
|
|
182
|
-
}
|
|
183
|
-
export function writeWatchLease(squareState, name, lease) {
|
|
184
|
-
squareState.runtime.leases[canonicalRuntimeName(squareState, name)] = lease;
|
|
54
|
+
const own = facts.activityHeads({ afterIndex: boundary, actors: [name] }, { edge: 'newest', limit: 1 }).items[0]?.index;
|
|
55
|
+
const evidence = Math.max(boundary, own ?? boundary, facts.receiptFacts(name, boundary).latestActorActivityIndex ?? boundary);
|
|
56
|
+
return facts.activityHeads({ afterIndex: boundary, throughIndex: evidence, kinds: ['say', 'done'] }, { edge: 'newest', limit: 1 }).items[0]?.index ?? -1;
|
|
185
57
|
}
|
|
186
|
-
export function
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
return false;
|
|
190
|
-
delete squareState.runtime.leases[key];
|
|
191
|
-
return true;
|
|
58
|
+
export function freshWatchLease(facts, name, at = Date.now()) {
|
|
59
|
+
const lease = facts.lease(name);
|
|
60
|
+
return lease === undefined || lease.expiresAt <= at || at - lease.heartbeatAt > WATCH_STALE_MS ? undefined : lease;
|
|
192
61
|
}
|
package/dist/square-actions.d.ts
CHANGED
|
@@ -1,21 +1,24 @@
|
|
|
1
|
-
import { type SquareState } from './model.js';
|
|
2
1
|
import type { WakeTransportPort } from './ports.js';
|
|
3
|
-
import type { Activity, CatchOptions,
|
|
4
|
-
import { type
|
|
2
|
+
import type { Activity, CatchOptions, ExpressOptions, ExpressResult, ExpressionObservation, ListenerChangeResult, OperationControl, OwnershipFenceOptions } from './square-facade.js';
|
|
3
|
+
import { type CatchSelection } from './catch-decisions.js';
|
|
5
4
|
import { type HostContext } from './participant-host.js';
|
|
6
5
|
export interface OperationContext extends HostContext {
|
|
7
6
|
readonly wakeTransport?: WakeTransportPort;
|
|
8
7
|
}
|
|
9
8
|
export type { OwnershipFenceOptions };
|
|
10
|
-
export declare function catchUp(square: OperationContext, name: string, options?: CatchOptions,
|
|
9
|
+
export declare function catchUp(square: OperationContext, name: string, options?: CatchOptions, control?: OperationControl): Promise<CatchSelection>;
|
|
10
|
+
export declare function catchUp(square: OperationContext, name: string, options: CatchOptions, control: OperationControl | undefined, leaseId: string): Promise<CatchSelection | null>;
|
|
11
11
|
export declare function join(square: OperationContext, name: string, control?: OperationControl): Promise<{
|
|
12
12
|
readonly name: string;
|
|
13
13
|
readonly activity: Activity | null;
|
|
14
|
+
readonly participantCount: number;
|
|
15
|
+
readonly reconnected: boolean;
|
|
14
16
|
}>;
|
|
15
|
-
/**
|
|
17
|
+
/** Takeover holds the host CAS fence across the single done+join artifact transaction. */
|
|
16
18
|
export declare function takeover(square: OperationContext, name: string, _oldSessionIds?: readonly string[], control?: OperationControl): Promise<{
|
|
17
19
|
readonly name: string;
|
|
18
20
|
readonly activities: readonly Activity[];
|
|
21
|
+
readonly participantCount: number;
|
|
19
22
|
readonly epoch?: number;
|
|
20
23
|
}>;
|
|
21
24
|
export declare function implicitJoin(square: OperationContext, name: string, control?: OperationControl): Promise<{
|
|
@@ -23,28 +26,15 @@ export declare function implicitJoin(square: OperationContext, name: string, con
|
|
|
23
26
|
readonly state: 'joined' | 'active' | 'done';
|
|
24
27
|
readonly activity: Activity | null;
|
|
25
28
|
}>;
|
|
26
|
-
export
|
|
27
|
-
|
|
28
|
-
readonly activity: Activity | null;
|
|
29
|
+
export interface ExpressCommittedResult extends ExpressResult {
|
|
30
|
+
readonly observation: ExpressionObservation;
|
|
29
31
|
}
|
|
32
|
+
export declare function express(square: OperationContext, name: string, body: string, options?: ExpressOptions, control?: OperationControl): Promise<ExpressCommittedResult>;
|
|
30
33
|
export declare function listen(square: OperationContext, actor: string, target: string, control?: OperationControl): Promise<ListenerChangeResult>;
|
|
31
34
|
export declare function ignore(square: OperationContext, actor: string, target: string, control?: OperationControl): Promise<ListenerChangeResult>;
|
|
32
35
|
export declare function listening(square: OperationContext, actor: string, control?: OperationControl): Promise<readonly string[]>;
|
|
33
36
|
export declare function done(square: OperationContext, name: string, body?: string, fence?: OwnershipFenceOptions, control?: OperationControl): Promise<ExpressResult>;
|
|
34
|
-
/**
|
|
35
|
-
* End one session's ownership of a participant inside the ownership claim critical
|
|
36
|
-
* section. The artifact `done` (when this session is still the owner) and retirement of
|
|
37
|
-
* this session's routes share one transaction, and the exact captured presence row is
|
|
38
|
-
* removed only while the lock is still held. A rejoin or takeover therefore lands either
|
|
39
|
-
* before the whole cleanup — and is part of the state being ended — or after it, with
|
|
40
|
-
* fresh presence and route rows that this cleanup can never touch.
|
|
41
|
-
*/
|
|
42
37
|
export declare function endOwnedSession(square: OperationContext, name: string, sessionId: string, expectedEpoch?: number): Promise<ExpressResult | null>;
|
|
43
|
-
/**
|
|
44
|
-
* Retire an ended session's orphan routes when no participant name is known. The
|
|
45
|
-
* ownership claim lock is held across the ledger read and the artifact transaction, so a
|
|
46
|
-
* rejoin that claims first is seen as a live participant and its route survives.
|
|
47
|
-
*/
|
|
48
38
|
export declare function retireEndedSessionRoutes(square: OperationContext, sessionId: string): Promise<void>;
|
|
49
39
|
export declare function hold(square: OperationContext, name: string, reason?: string, control?: OperationControl): Promise<ExpressResult>;
|
|
50
40
|
export declare function resume(square: OperationContext, name: string, control?: OperationControl): Promise<ExpressResult>;
|