@astrosheep/square 0.3.94 → 0.3.95
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/artifact.js +1 -1
- package/dist/attention.d.ts +19 -0
- package/dist/attention.js +30 -0
- package/dist/boundary-presentation.js +33 -40
- package/dist/catch-decisions.d.ts +1 -2
- package/dist/catch-decisions.js +41 -21
- package/dist/cli/context.js +0 -2
- package/dist/cli/express-presentation.js +3 -3
- package/dist/cli/json.js +1 -1
- package/dist/cli/program.js +1 -1
- package/dist/cli/registry.js +1 -3
- package/dist/cli/square-commands.d.ts +0 -2
- package/dist/cli/square-commands.js +21 -27
- package/dist/decisions.d.ts +0 -5
- package/dist/decisions.js +0 -13
- package/dist/delivery-attempts.d.ts +52 -0
- package/dist/delivery-attempts.js +73 -0
- package/dist/delivery-effects.d.ts +139 -0
- package/dist/delivery-effects.js +163 -0
- package/dist/delivery-operations.js +43 -68
- package/dist/delivery-primitives.d.ts +5 -0
- package/dist/delivery-primitives.js +3 -0
- package/dist/delivery.d.ts +1 -1
- package/dist/delivery.js +6 -5
- package/dist/help.js +4 -6
- package/dist/http-delivery.d.ts +16 -0
- package/dist/http-delivery.js +101 -0
- package/dist/model.d.ts +4 -6
- package/dist/model.js +1 -1
- package/dist/notifications.js +2 -0
- package/dist/operation-presentation.d.ts +1 -2
- package/dist/operation-presentation.js +12 -20
- package/dist/ports.d.ts +5 -14
- package/dist/presentation-operations.d.ts +14 -19
- package/dist/presentation-operations.js +47 -57
- package/dist/presentation.d.ts +2 -9
- package/dist/presentation.js +13 -48
- package/dist/receive.d.ts +66 -0
- package/dist/receive.js +54 -0
- package/dist/runtime.d.ts +0 -1
- package/dist/runtime.js +2 -3
- package/dist/sqlite-square.d.ts +0 -1
- package/dist/sqlite-square.js +29 -55
- package/dist/square-api.d.ts +1 -1
- package/dist/square-api.js +1 -1
- package/dist/square-core.d.ts +0 -9
- package/dist/square-domain.js +9 -31
- package/dist/square-facade.d.ts +5 -21
- package/dist/square-legacy-framing.d.ts +2 -0
- package/dist/square-legacy-framing.js +8 -0
- package/dist/square-migration.d.ts +3 -1
- package/dist/square-migration.js +46 -13
- package/dist/square-receive.d.ts +6 -0
- package/dist/square-receive.js +18 -0
- package/dist/square-sqlite.d.ts +5 -3
- package/dist/square-sqlite.js +89 -90
- package/dist/square-tools.js +3 -11
- package/dist/views.d.ts +2 -3
- package/dist/views.js +13 -19
- package/dist/wakes.d.ts +0 -3
- package/dist/wakes.js +3 -5
- package/examples/symmetric-domains.mjs +250 -0
- package/guides/application-facade-delivery-evidence.md +5 -5
- package/guides/attention-primitive.md +32 -0
- package/guides/change-waits.md +2 -2
- package/guides/codex-delivery.md +1 -1
- package/guides/delivery-primitives.md +180 -0
- package/guides/mcp.md +1 -1
- package/guides/migration.md +12 -6
- package/guides/participant-ownership.md +1 -1
- package/guides/pi-tools.md +2 -2
- package/guides/primitive-catch-consolidation.md +5 -5
- package/guides/primitive-history-consolidation.md +2 -2
- package/guides/primitive-status-consolidation.md +3 -3
- package/guides/primitive-storage-consolidation.md +1 -1
- package/guides/receive-primitive.md +90 -0
- package/guides/row-runtime-delivery-evidence.md +1 -1
- package/guides/row-storage-design.md +17 -23
- package/guides/square-api.md +77 -10
- package/guides/symmetric-domains.md +92 -0
- package/package.json +14 -1
- package/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/plugins/claude/skills/square/SKILL.md +2 -6
- package/plugins/codex/.codex-plugin/plugin.json +1 -1
- package/skills/square/SKILL.md +2 -6
package/dist/square-facade.d.ts
CHANGED
|
@@ -5,12 +5,12 @@ import type { Owner, StoredAct, WakeAddress, ActivityMetadata, DirectedNotificat
|
|
|
5
5
|
import type { WakeTransportPort, SquareResourceOwner } from './ports.js';
|
|
6
6
|
export type { ActivityId, Perception, Reach } from './square-core.js';
|
|
7
7
|
export type { Owner, WakeAddress, ActivityMetadata, JsonValue, DirectedNotificationRoute } from './model.js';
|
|
8
|
-
/** Indexed archive event, including read
|
|
8
|
+
/** Indexed archive event, including read bookkeeping. */
|
|
9
9
|
export type ArchiveRecord = Readonly<StoredAct>;
|
|
10
10
|
export interface Activity {
|
|
11
11
|
readonly id: ActivityId;
|
|
12
12
|
readonly at: number;
|
|
13
|
-
readonly kind: 'join' | 'say' | 'done' | '
|
|
13
|
+
readonly kind: 'join' | 'say' | 'done' | 'listen' | 'ignore' | 'unlisten';
|
|
14
14
|
readonly actor: string;
|
|
15
15
|
readonly body?: string;
|
|
16
16
|
readonly metadata?: ActivityMetadata;
|
|
@@ -85,10 +85,8 @@ export interface CatchWaitStart {
|
|
|
85
85
|
}
|
|
86
86
|
export type OperationProgress = {
|
|
87
87
|
readonly kind: 'waiting';
|
|
88
|
-
readonly reason: '
|
|
88
|
+
readonly reason: 'throttled';
|
|
89
89
|
readonly delayMs?: number;
|
|
90
|
-
readonly holder?: string;
|
|
91
|
-
readonly holdReason?: string;
|
|
92
90
|
} | ({
|
|
93
91
|
readonly kind: 'catch-started';
|
|
94
92
|
readonly participant: string;
|
|
@@ -135,10 +133,6 @@ export interface SquareSnapshot {
|
|
|
135
133
|
readonly actCount: number;
|
|
136
134
|
readonly hardCap: number | null;
|
|
137
135
|
readonly throttlePerMinute?: number;
|
|
138
|
-
readonly held: {
|
|
139
|
-
readonly by: string;
|
|
140
|
-
readonly reason?: string;
|
|
141
|
-
} | null;
|
|
142
136
|
readonly participants: readonly Pick<ParticipantSummary, 'name' | 'presence' | 'listening'>[];
|
|
143
137
|
delivered(name: string, id: ActivityId): boolean;
|
|
144
138
|
}
|
|
@@ -183,8 +177,6 @@ export interface Participant {
|
|
|
183
177
|
unlisten(target: string, options?: ObservationOptions, control?: OperationControl): Promise<ListenerChangeResult>;
|
|
184
178
|
listening(options?: ObservationOptions, control?: OperationControl): Promise<ListeningResult>;
|
|
185
179
|
catch(options?: CatchOptions, control?: OperationControl): Promise<CatchResult>;
|
|
186
|
-
hold(reason?: string, options?: ObservationOptions, control?: OperationControl): Promise<LifecycleResult>;
|
|
187
|
-
resume(options?: ObservationOptions, control?: OperationControl): Promise<LifecycleResult>;
|
|
188
180
|
/** Leave without a message. Only an omitted or empty body is accepted. */
|
|
189
181
|
done(body?: string, options?: ObservationOptions, control?: OperationControl): Promise<LifecycleResult>;
|
|
190
182
|
deferDelivery(input: Readonly<{
|
|
@@ -220,12 +212,6 @@ export interface StatusResult {
|
|
|
220
212
|
readonly participants: readonly ParticipantSummary[];
|
|
221
213
|
readonly now: number;
|
|
222
214
|
readonly throttlePerMinute?: number;
|
|
223
|
-
/** Non-null whenever held; by is present with an actor and omitted only for historical actorless holds. */
|
|
224
|
-
readonly held: {
|
|
225
|
-
readonly by?: string;
|
|
226
|
-
readonly reason?: string;
|
|
227
|
-
readonly at?: number;
|
|
228
|
-
} | null;
|
|
229
215
|
readonly latestActivity?: Activity;
|
|
230
216
|
readonly observation?: StatusObservation;
|
|
231
217
|
}
|
|
@@ -267,7 +253,6 @@ export interface InboxResult {
|
|
|
267
253
|
export interface RecoveryResult {
|
|
268
254
|
readonly participant?: string;
|
|
269
255
|
readonly standingCount?: number;
|
|
270
|
-
readonly held?: boolean;
|
|
271
256
|
readonly ownActivityCount?: number;
|
|
272
257
|
readonly hardCap?: number | null;
|
|
273
258
|
readonly activitySummaries?: readonly UnreadActivitySummary[];
|
|
@@ -310,7 +295,6 @@ export interface CatchPresence {
|
|
|
310
295
|
export interface SquareObservation {
|
|
311
296
|
readonly location: string;
|
|
312
297
|
readonly standingCount: number;
|
|
313
|
-
readonly held: boolean;
|
|
314
298
|
readonly now: number;
|
|
315
299
|
readonly participant?: string;
|
|
316
300
|
}
|
|
@@ -320,7 +304,7 @@ export interface JoinObservation extends SquareObservation {
|
|
|
320
304
|
/** The receipt succeeded, but optional recent-history/context enrichment was unavailable. */
|
|
321
305
|
readonly enrichmentUnavailable?: true;
|
|
322
306
|
}
|
|
323
|
-
export interface ExpressionObservation extends Pick<SquareObservation, 'standingCount' | '
|
|
307
|
+
export interface ExpressionObservation extends Pick<SquareObservation, 'standingCount' | 'now'> {
|
|
324
308
|
readonly ownActivityCount: number;
|
|
325
309
|
readonly hardCap: number | null;
|
|
326
310
|
}
|
|
@@ -361,7 +345,7 @@ export interface ListenerObservation extends SquareObservation {
|
|
|
361
345
|
readonly participant: string;
|
|
362
346
|
readonly target: string;
|
|
363
347
|
}
|
|
364
|
-
export interface StatusObservation extends Omit<SquareObservation, 'now'
|
|
348
|
+
export interface StatusObservation extends Omit<SquareObservation, 'now'>, PresenceClassification {
|
|
365
349
|
readonly knownParticipantCount: number;
|
|
366
350
|
readonly latestPerception?: Perception;
|
|
367
351
|
readonly joins: readonly {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { DatabaseSync } from 'node:sqlite';
|
|
2
2
|
export declare const FORMAT4_ADDED_OBJECTS: ReadonlySet<string>;
|
|
3
3
|
export declare const FORMAT4_REPLACED_OBJECTS: ReadonlySet<string>;
|
|
4
|
+
/** Historical activity framing only; no runtime activity decoder accepts these kinds. */
|
|
5
|
+
export declare function legacyActivitySchema(currentSchemaSql: string): string;
|
|
4
6
|
/**
|
|
5
7
|
* Read-only recognition of the exact row framing accepted by explicit migration.
|
|
6
8
|
* It inspects identity, owned schema and journal mode only; it never reads row
|
|
@@ -15,6 +15,14 @@ CREATE INDEX route_session ON routes(session_json, position);`;
|
|
|
15
15
|
function normalizedSql(sql) {
|
|
16
16
|
return sql.trim().replace(/;$/, '').replace(/\s+/g, ' ').replace(/\s*([(),=])\s*/g, '$1');
|
|
17
17
|
}
|
|
18
|
+
/** Historical activity framing only; no runtime activity decoder accepts these kinds. */
|
|
19
|
+
export function legacyActivitySchema(currentSchemaSql) {
|
|
20
|
+
return currentSchemaSql
|
|
21
|
+
.replace("kind IN ('join','done','say','read','listen','ignore','unlisten')", "kind IN ('join','done','say','hold','resume','read','listen','ignore','unlisten')")
|
|
22
|
+
.replace(' actor_json TEXT COLLATE BINARY NOT NULL,', ' actor_json TEXT COLLATE BINARY,')
|
|
23
|
+
.replace(' actor_key_json TEXT COLLATE BINARY NOT NULL,', ' actor_key_json TEXT COLLATE BINARY,')
|
|
24
|
+
.replace(" CHECK (kind = 'say' OR (reach IS NULL AND reply_index IS NULL))", " CHECK ((actor_json IS NULL) = (actor_key_json IS NULL)),\n CHECK (kind IN ('hold','resume') OR actor_json IS NOT NULL),\n CHECK (kind = 'say' OR (reach IS NULL AND reply_index IS NULL))");
|
|
25
|
+
}
|
|
18
26
|
function legacyRowSchema(currentSchemaSql, version) {
|
|
19
27
|
const statements = currentSchemaSql.split(';').map((statement) => statement.trim()).filter(Boolean)
|
|
20
28
|
.filter((statement) => {
|
|
@@ -20,8 +20,10 @@ export interface MigrationOutcome {
|
|
|
20
20
|
/**
|
|
21
21
|
* Explicit conversion of the supported legacy formats. Row-backed versions 2 and 3 are
|
|
22
22
|
* preflighted read-only, then receive ownership/evidence and deferral storage in one
|
|
23
|
-
* format-
|
|
23
|
+
* format-8 transaction. Formats 4/5 gain attachment; format 4 also gains empty deferrals.
|
|
24
24
|
* All legacy seats are encoded as opaque owners, preserving format-6 attachment.
|
|
25
|
+
* Every source drops obsolete activities and their identity references, clears dangling
|
|
26
|
+
* replies and rebuilds derived indices; surviving ids and allocation watermarks remain stable.
|
|
25
27
|
* Legacy delivery evidence is copied from HostLedger only when its owner/session mapping is
|
|
26
28
|
* unique; no source record is retired. Version 1 is not a supported source for this format transition.
|
|
27
29
|
*/
|
package/dist/square-migration.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DatabaseSync } from 'node:sqlite';
|
|
1
2
|
import { createHash } from 'node:crypto';
|
|
2
3
|
import { openExistingSquareDatabase } from './artifact.js';
|
|
3
4
|
import { inSqliteTransaction } from './sqlite-transaction.js';
|
|
@@ -7,7 +8,7 @@ import { formatActivityId, isWakeRouteKind, nameKey } from './model.js';
|
|
|
7
8
|
import { parseActivityId } from './square-core.js';
|
|
8
9
|
import { readLegacyHostData } from './square-migration-host-ledger.js';
|
|
9
10
|
import { legacyRowFramingIssue, FORMAT4_ADDED_OBJECTS } from './square-legacy-framing.js';
|
|
10
|
-
import { APPLICATION_ID, ACTIVITIES_TABLE_SQL, ACTIVITY_INDEXES_SQL, CURRENT_USER_VERSION, V2_USER_VERSION, V3_USER_VERSION, V4_USER_VERSION, V5_USER_VERSION, V6_USER_VERSION, SCHEMA_SQL, FORMAT4_SCHEMA_SQL, DELIVERY_DEFERRALS_SQL, validateRowFraming, inspectSqlite, createSqliteDriver, invalidArtifact, validateStoredActivity } from './square-sqlite.js';
|
|
11
|
+
import { APPLICATION_ID, ACTIVITIES_TABLE_SQL, ACTIVITY_INDEXES_SQL, CURRENT_USER_VERSION, V2_USER_VERSION, V3_USER_VERSION, V4_USER_VERSION, V5_USER_VERSION, V6_USER_VERSION, V7_USER_VERSION, SCHEMA_SQL, FORMAT4_SCHEMA_SQL, DELIVERY_DEFERRALS_SQL, validateRowFraming, inspectSqlite, createSqliteDriver, invalidArtifact, validateStoredActivity, exportSqliteState, initializeSqlite } from './square-sqlite.js';
|
|
11
12
|
function isObject(value) {
|
|
12
13
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
13
14
|
}
|
|
@@ -134,15 +135,44 @@ function standing(database) {
|
|
|
134
135
|
return createSqliteDriver(database).roster().filter((participant) => participant.joined).length;
|
|
135
136
|
}
|
|
136
137
|
const ACTIVITY_INDEX_NAMES = ['activity_kind_index', 'activity_actor_index', 'activity_say_actor_index', 'activity_say_time', 'activity_bell_actor_time'];
|
|
137
|
-
function
|
|
138
|
+
function migrateActivities(database) {
|
|
139
|
+
// Only activity identity references are deleted. Range watermarks (read.through and
|
|
140
|
+
// delivery cancellation boundaries) remain meaningful even when their endpoint is gone.
|
|
141
|
+
for (const table of ['landed_audience', 'receipts', 'delivery_evidence']) {
|
|
142
|
+
database.exec(`DELETE FROM ${table} WHERE act_index IN (SELECT act_index FROM activities WHERE kind IN ('hold','resume'));`);
|
|
143
|
+
}
|
|
138
144
|
database.exec([
|
|
145
|
+
"UPDATE activities SET reply_index=NULL WHERE reply_index IN (SELECT act_index FROM activities WHERE kind IN ('hold','resume'));",
|
|
139
146
|
...ACTIVITY_INDEX_NAMES.map((name) => `DROP INDEX ${name};`),
|
|
140
|
-
'ALTER TABLE activities RENAME TO
|
|
147
|
+
'ALTER TABLE activities RENAME TO activities_legacy;',
|
|
141
148
|
ACTIVITIES_TABLE_SQL,
|
|
142
|
-
|
|
143
|
-
'DROP TABLE
|
|
149
|
+
"INSERT INTO activities(act_index,at,kind,actor_json,actor_key_json,reach,reply_index,payload_json) SELECT act_index,at,kind,actor_json,actor_key_json,reach,reply_index,payload_json FROM activities_legacy WHERE kind NOT IN ('hold','resume') ORDER BY act_index;",
|
|
150
|
+
'DROP TABLE activities_legacy;',
|
|
144
151
|
...ACTIVITY_INDEXES_SQL.map((sql) => `${sql};`),
|
|
145
152
|
].join('\n'));
|
|
153
|
+
// Actor-bearing deleted activities and cleared replies can change maintained indices.
|
|
154
|
+
// Replay surviving facts only, without lowering the authoritative next allocator.
|
|
155
|
+
const names = database.prepare('SELECT name_key_json,name_json FROM participants').all();
|
|
156
|
+
const rebuilt = new DatabaseSync(':memory:');
|
|
157
|
+
try {
|
|
158
|
+
initializeSqlite(rebuilt, exportSqliteState(database));
|
|
159
|
+
// Canonical spelling is an established identity fact, not the spelling of
|
|
160
|
+
// whichever actor activity happens to survive this migration first.
|
|
161
|
+
const retainName = rebuilt.prepare('UPDATE participants SET name_json=? WHERE name_key_json=?');
|
|
162
|
+
for (const row of names)
|
|
163
|
+
retainName.run(row.name_json, row.name_key_json);
|
|
164
|
+
for (const table of ['participants', 'attention', 'landed_audience']) {
|
|
165
|
+
database.exec(`DELETE FROM ${table};`);
|
|
166
|
+
for (const row of rebuilt.prepare(`SELECT * FROM ${table}`).all()) {
|
|
167
|
+
const columns = Object.keys(row);
|
|
168
|
+
database.prepare(`INSERT INTO ${table}(${columns.join(',')}) VALUES(${columns.map(() => '?').join(',')})`)
|
|
169
|
+
.run(...Object.values(row));
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
finally {
|
|
174
|
+
rebuilt.close();
|
|
175
|
+
}
|
|
146
176
|
}
|
|
147
177
|
function validateCurrentFraming(database, location) {
|
|
148
178
|
validateRowFraming(database, CURRENT_USER_VERSION, location);
|
|
@@ -282,7 +312,7 @@ function inspectLegacyRowArtifact(database, location, host) {
|
|
|
282
312
|
const driver = createSqliteDriver(database);
|
|
283
313
|
let activityCount = 0;
|
|
284
314
|
let previous = -1;
|
|
285
|
-
for (const row of database.prepare(
|
|
315
|
+
for (const row of database.prepare("SELECT act_index FROM activities WHERE kind NOT IN ('hold','resume') ORDER BY act_index").iterate()) {
|
|
286
316
|
const index = sourceInteger(row.act_index);
|
|
287
317
|
assertSource(index > previous && index < nextActIndex, 'activity index is malformed or unassigned.');
|
|
288
318
|
const activity = driver.activity(index);
|
|
@@ -389,7 +419,7 @@ function planLegacyDeliveries(records, seats, driver) {
|
|
|
389
419
|
continue;
|
|
390
420
|
const joined = establishingJoin(driver, participant);
|
|
391
421
|
const generation = formatActivityId(joined);
|
|
392
|
-
if (index <= joined || driver.
|
|
422
|
+
if (index <= joined || driver.activityHeads({ indexes: [index], kinds: ['say'] }, { edge: 'oldest', limit: 1 }).items.length === 0 || driver.directedAt(participant.name, index) === undefined)
|
|
393
423
|
continue;
|
|
394
424
|
if (participant.done) {
|
|
395
425
|
const done = driver.activityHeads({ actors: [participant.name], kinds: ['done'] }, { edge: 'newest', limit: 1 }).items[0];
|
|
@@ -488,6 +518,7 @@ function upgradeRowArtifact(database, location, plan) {
|
|
|
488
518
|
importOwnershipAndEvidence(database, plan);
|
|
489
519
|
database.exec('DROP TABLE routes;');
|
|
490
520
|
database.exec(DELIVERY_DEFERRALS_SQL);
|
|
521
|
+
migrateActivities(database);
|
|
491
522
|
database.exec(`PRAGMA user_version = ${CURRENT_USER_VERSION};`);
|
|
492
523
|
validateCurrentFraming(database, location);
|
|
493
524
|
}
|
|
@@ -501,7 +532,7 @@ function validateMigrationSource(database, location) {
|
|
|
501
532
|
throw invalidArtifact(issue);
|
|
502
533
|
return before.userVersion;
|
|
503
534
|
}
|
|
504
|
-
if (before.userVersion === V4_USER_VERSION || before.userVersion === V5_USER_VERSION || before.userVersion === V6_USER_VERSION) {
|
|
535
|
+
if (before.userVersion === V4_USER_VERSION || before.userVersion === V5_USER_VERSION || before.userVersion === V6_USER_VERSION || before.userVersion === V7_USER_VERSION) {
|
|
505
536
|
validateRowFraming(database, before.userVersion, location);
|
|
506
537
|
return before.userVersion;
|
|
507
538
|
}
|
|
@@ -514,8 +545,10 @@ function validateMigrationSource(database, location) {
|
|
|
514
545
|
/**
|
|
515
546
|
* Explicit conversion of the supported legacy formats. Row-backed versions 2 and 3 are
|
|
516
547
|
* preflighted read-only, then receive ownership/evidence and deferral storage in one
|
|
517
|
-
* format-
|
|
548
|
+
* format-8 transaction. Formats 4/5 gain attachment; format 4 also gains empty deferrals.
|
|
518
549
|
* All legacy seats are encoded as opaque owners, preserving format-6 attachment.
|
|
550
|
+
* Every source drops obsolete activities and their identity references, clears dangling
|
|
551
|
+
* replies and rebuilds derived indices; surviving ids and allocation watermarks remain stable.
|
|
519
552
|
* Legacy delivery evidence is copied from HostLedger only when its owner/session mapping is
|
|
520
553
|
* unique; no source record is retired. Version 1 is not a supported source for this format transition.
|
|
521
554
|
*/
|
|
@@ -526,13 +559,15 @@ export async function migrateSquareFile(location, signal, env = process.env) {
|
|
|
526
559
|
const source = await inSqliteTransaction(database, false, () => validateMigrationSource(database, squarePath), value => value, signal);
|
|
527
560
|
if (source === undefined)
|
|
528
561
|
return { status: 'already-current', standing: standing(database) };
|
|
529
|
-
if (source === V4_USER_VERSION || source === V5_USER_VERSION || source === V6_USER_VERSION) {
|
|
562
|
+
if (source === V4_USER_VERSION || source === V5_USER_VERSION || source === V6_USER_VERSION || source === V7_USER_VERSION) {
|
|
530
563
|
return await inSqliteTransaction(database, true, () => {
|
|
531
564
|
assertSource(validateMigrationSource(database, squarePath) === source, 'source format changed during migration preflight.');
|
|
532
565
|
}, () => {
|
|
533
566
|
if (source === V4_USER_VERSION)
|
|
534
567
|
database.exec(DELIVERY_DEFERRALS_SQL);
|
|
535
|
-
|
|
568
|
+
if (source !== V7_USER_VERSION)
|
|
569
|
+
migrateSeatOwnership(database, source);
|
|
570
|
+
migrateActivities(database);
|
|
536
571
|
database.exec(`PRAGMA user_version = ${CURRENT_USER_VERSION};`);
|
|
537
572
|
validateCurrentFraming(database, squarePath);
|
|
538
573
|
return { status: 'migrated', standing: standing(database) };
|
|
@@ -552,8 +587,6 @@ export async function migrateSquareFile(location, signal, env = process.env) {
|
|
|
552
587
|
assertSource(lockedPlan.sourceToken === plan.sourceToken, 'source changed during migration preflight.');
|
|
553
588
|
result.plan = lockedPlan;
|
|
554
589
|
}, () => {
|
|
555
|
-
if (source === 2)
|
|
556
|
-
rebuildV2Activities(database);
|
|
557
590
|
const migratedPlan = result.plan;
|
|
558
591
|
upgradeRowArtifact(database, squarePath, migratedPlan);
|
|
559
592
|
result.outcome = { status: 'migrated', standing: migratedPlan.standing, counts: migratedPlan.counts };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { AudienceRoute } from './attention.js';
|
|
2
|
+
import type { StoredAct } from './model.js';
|
|
3
|
+
import type { DirectedFilter, SquareRead } from './ports.js';
|
|
4
|
+
import type { ReceiveRead } from './receive.js';
|
|
5
|
+
/** Transaction-local projections only; the artifact still owns indexed selection and bodies. */
|
|
6
|
+
export declare function squareReceiveRead(facts: SquareRead): ReceiveRead<number, StoredAct, AudienceRoute, DirectedFilter>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Transaction-local projections only; the artifact still owns indexed selection and bodies. */
|
|
2
|
+
export function squareReceiveRead(facts) {
|
|
3
|
+
const filter = (query, unconsumed) => {
|
|
4
|
+
const { unseenOnly: _, ...rest } = query;
|
|
5
|
+
return unconsumed ? { ...rest, unseenOnly: true } : rest;
|
|
6
|
+
};
|
|
7
|
+
return {
|
|
8
|
+
heads: (recipient, query, options) => facts.directed(recipient, filter(query, options.unconsumed), { edge: 'oldest', limit: options.limit })
|
|
9
|
+
.items.map(item => ({ key: item.index, via: item.route })),
|
|
10
|
+
addressed(recipient, index) {
|
|
11
|
+
const head = facts.directedAt(recipient, index);
|
|
12
|
+
return head === undefined ? undefined : { key: head.index, via: head.route };
|
|
13
|
+
},
|
|
14
|
+
load: keys => new Map(facts.activities(keys).map(item => [item.index, item])),
|
|
15
|
+
count: (recipient, query, unconsumed) => facts.directedCount(recipient, filter(query, unconsumed)),
|
|
16
|
+
receipt: ref => facts.receipt(ref.recipient, ref.item),
|
|
17
|
+
};
|
|
18
|
+
}
|
package/dist/square-sqlite.d.ts
CHANGED
|
@@ -23,7 +23,8 @@ export declare const V3_USER_VERSION = 3;
|
|
|
23
23
|
export declare const V4_USER_VERSION = 4;
|
|
24
24
|
export declare const V5_USER_VERSION = 5;
|
|
25
25
|
export declare const V6_USER_VERSION = 6;
|
|
26
|
-
export declare const
|
|
26
|
+
export declare const V7_USER_VERSION = 7;
|
|
27
|
+
export declare const CURRENT_USER_VERSION = 8;
|
|
27
28
|
export declare const V1_SNAPSHOT_TABLE = "square_snapshot";
|
|
28
29
|
export interface LegacyFraming {
|
|
29
30
|
readonly applicationId: number;
|
|
@@ -37,17 +38,18 @@ export interface LegacyFraming {
|
|
|
37
38
|
* migration. Anything else is unrelated or unsupported, not repaired.
|
|
38
39
|
*/
|
|
39
40
|
export declare function validateLegacyFraming(database: DatabaseSync, applicationId: number, location?: string): LegacyFraming;
|
|
40
|
-
export declare const ACTIVITIES_TABLE_SQL = "CREATE TABLE activities (\n act_index INTEGER PRIMARY KEY CHECK (act_index BETWEEN 0 AND 9007199254740991),\n at REAL NOT NULL,\n kind TEXT NOT NULL CHECK (kind IN ('join','done','say','
|
|
41
|
+
export declare const ACTIVITIES_TABLE_SQL = "CREATE TABLE activities (\n act_index INTEGER PRIMARY KEY CHECK (act_index BETWEEN 0 AND 9007199254740991),\n at REAL NOT NULL,\n kind TEXT NOT NULL CHECK (kind IN ('join','done','say','read','listen','ignore','unlisten')),\n actor_json TEXT COLLATE BINARY NOT NULL,\n actor_key_json TEXT COLLATE BINARY NOT NULL,\n reach TEXT CHECK (reach = 'bell'),\n reply_index INTEGER CHECK (reply_index >= 0 AND reply_index < act_index),\n payload_json TEXT NOT NULL CHECK (json_valid(payload_json)),\n CHECK (kind = 'say' OR (reach IS NULL AND reply_index IS NULL))\n);";
|
|
41
42
|
export declare const ACTIVITY_INDEXES_SQL: readonly ["CREATE INDEX activity_kind_index ON activities(kind, act_index)", "CREATE INDEX activity_actor_index ON activities(actor_key_json, act_index)", "CREATE INDEX activity_say_actor_index ON activities(actor_key_json, act_index) WHERE kind='say'", "CREATE INDEX activity_say_time ON activities(at, act_index) WHERE kind='say'", "CREATE INDEX activity_bell_actor_time ON activities(actor_key_json, at, act_index) WHERE kind='say' AND reach='bell'"];
|
|
42
43
|
export declare const DELIVERY_DEFERRALS_SQL = "CREATE TABLE delivery_deferrals (\n participant_key_json TEXT COLLATE BINARY NOT NULL,\n participant_json TEXT NOT NULL,\n generation_json TEXT NOT NULL,\n deferral_id_json TEXT NOT NULL,\n match_json TEXT NOT NULL CHECK (json_valid(match_json)),\n expires_at REAL NOT NULL,\n PRIMARY KEY (participant_key_json,generation_json,deferral_id_json)\n) WITHOUT ROWID;\nCREATE INDEX delivery_deferral_expiry ON delivery_deferrals(participant_key_json,generation_json,expires_at);";
|
|
43
44
|
export declare const SCHEMA_SQL: string;
|
|
45
|
+
export declare const FORMAT7_SCHEMA_SQL: string;
|
|
44
46
|
export declare const FORMAT6_SCHEMA_SQL: string;
|
|
45
47
|
export declare const FORMAT5_SCHEMA_SQL: string;
|
|
46
48
|
export declare const FORMAT4_SCHEMA_SQL: string;
|
|
47
49
|
export declare function invalidArtifact(detail: string): SquareError;
|
|
48
50
|
export declare function validateStoredActivity(value: unknown): StoredAct;
|
|
49
51
|
export declare function validateWatchLease(value: unknown): WatchLease;
|
|
50
|
-
export declare function validateRowFraming(db: DatabaseSync, version: 2 | 3 | 4 | 5 | 6 | 7, location?: string): void;
|
|
52
|
+
export declare function validateRowFraming(db: DatabaseSync, version: 2 | 3 | 4 | 5 | 6 | 7 | 8, location?: string): void;
|
|
51
53
|
export declare function validateSqliteHeader(db: DatabaseSync, location?: string): SquareHeader;
|
|
52
54
|
export interface SqliteDriver extends SquareRead, LandingWriter {
|
|
53
55
|
readonly changed: boolean;
|