@maka/maka-cli 5.91.0 → 5.93.0

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.
Files changed (92) hide show
  1. package/bundle/typescript/package.json +1 -1
  2. package/bundle/typescript/src/commands/game/sideQuest/archetypes.js +9 -9
  3. package/bundle/typescript/src/commands/game/sideQuest/archetypes.js.map +1 -1
  4. package/bundle/typescript/src/commands/game/sideQuest/augmentations.d.ts +54 -3
  5. package/bundle/typescript/src/commands/game/sideQuest/augmentations.js +987 -53
  6. package/bundle/typescript/src/commands/game/sideQuest/augmentations.js.map +1 -1
  7. package/bundle/typescript/src/commands/game/sideQuest/commands/ask.d.ts +0 -14
  8. package/bundle/typescript/src/commands/game/sideQuest/commands/ask.js +22 -0
  9. package/bundle/typescript/src/commands/game/sideQuest/commands/ask.js.map +1 -1
  10. package/bundle/typescript/src/commands/game/sideQuest/commands/buy.js +14 -1
  11. package/bundle/typescript/src/commands/game/sideQuest/commands/buy.js.map +1 -1
  12. package/bundle/typescript/src/commands/game/sideQuest/commands/call.js +5 -1
  13. package/bundle/typescript/src/commands/game/sideQuest/commands/call.js.map +1 -1
  14. package/bundle/typescript/src/commands/game/sideQuest/commands/cast.js +7 -55
  15. package/bundle/typescript/src/commands/game/sideQuest/commands/cast.js.map +1 -1
  16. package/bundle/typescript/src/commands/game/sideQuest/commands/companions.js +5 -1
  17. package/bundle/typescript/src/commands/game/sideQuest/commands/companions.js.map +1 -1
  18. package/bundle/typescript/src/commands/game/sideQuest/commands/go.js +10 -1
  19. package/bundle/typescript/src/commands/game/sideQuest/commands/go.js.map +1 -1
  20. package/bundle/typescript/src/commands/game/sideQuest/commands/initiate.js +8 -1
  21. package/bundle/typescript/src/commands/game/sideQuest/commands/initiate.js.map +1 -1
  22. package/bundle/typescript/src/commands/game/sideQuest/commands/inv.js +3 -0
  23. package/bundle/typescript/src/commands/game/sideQuest/commands/inv.js.map +1 -1
  24. package/bundle/typescript/src/commands/game/sideQuest/commands/move.js +13 -7
  25. package/bundle/typescript/src/commands/game/sideQuest/commands/move.js.map +1 -1
  26. package/bundle/typescript/src/commands/game/sideQuest/commands/project.js +12 -0
  27. package/bundle/typescript/src/commands/game/sideQuest/commands/project.js.map +1 -1
  28. package/bundle/typescript/src/commands/game/sideQuest/commands/reload.js +1 -1
  29. package/bundle/typescript/src/commands/game/sideQuest/commands/sheet.js +7 -2
  30. package/bundle/typescript/src/commands/game/sideQuest/commands/sheet.js.map +1 -1
  31. package/bundle/typescript/src/commands/game/sideQuest/commands/use.js +3 -3
  32. package/bundle/typescript/src/commands/game/sideQuest/engine-version.d.ts +1 -1
  33. package/bundle/typescript/src/commands/game/sideQuest/engine-version.js +69 -1
  34. package/bundle/typescript/src/commands/game/sideQuest/engine-version.js.map +1 -1
  35. package/bundle/typescript/src/commands/game/sideQuest/factories/chargen-factory.d.ts +1 -1
  36. package/bundle/typescript/src/commands/game/sideQuest/factories/chargen-factory.js +90 -16
  37. package/bundle/typescript/src/commands/game/sideQuest/factories/chargen-factory.js.map +1 -1
  38. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.js +26 -3
  39. package/bundle/typescript/src/commands/game/sideQuest/factories/scene-chunks.js.map +1 -1
  40. package/bundle/typescript/src/commands/game/sideQuest/game.d.ts +95 -3
  41. package/bundle/typescript/src/commands/game/sideQuest/game.js +191 -13
  42. package/bundle/typescript/src/commands/game/sideQuest/game.js.map +1 -1
  43. package/bundle/typescript/src/commands/game/sideQuest/headless-harness.js +5 -1
  44. package/bundle/typescript/src/commands/game/sideQuest/headless-harness.js.map +1 -1
  45. package/bundle/typescript/src/commands/game/sideQuest/models/inventory.d.ts +13 -0
  46. package/bundle/typescript/src/commands/game/sideQuest/models/inventory.js +45 -2
  47. package/bundle/typescript/src/commands/game/sideQuest/models/inventory.js.map +1 -1
  48. package/bundle/typescript/src/commands/game/sideQuest/models/item.d.ts +65 -1
  49. package/bundle/typescript/src/commands/game/sideQuest/models/item.js +83 -1
  50. package/bundle/typescript/src/commands/game/sideQuest/models/item.js.map +1 -1
  51. package/bundle/typescript/src/commands/game/sideQuest/models/player.d.ts +126 -4
  52. package/bundle/typescript/src/commands/game/sideQuest/models/player.js +148 -15
  53. package/bundle/typescript/src/commands/game/sideQuest/models/player.js.map +1 -1
  54. package/bundle/typescript/src/commands/game/sideQuest/qualities.d.ts +33 -1
  55. package/bundle/typescript/src/commands/game/sideQuest/qualities.js +12 -2
  56. package/bundle/typescript/src/commands/game/sideQuest/qualities.js.map +1 -1
  57. package/bundle/typescript/src/commands/game/sideQuest/scenes/scene1.json +1 -1
  58. package/bundle/typescript/src/commands/game/sideQuest/scenes/scene2.json +4 -4
  59. package/bundle/typescript/src/commands/game/sideQuest/skill-groups.d.ts +120 -0
  60. package/bundle/typescript/src/commands/game/sideQuest/skill-groups.js +135 -0
  61. package/bundle/typescript/src/commands/game/sideQuest/skill-groups.js.map +1 -0
  62. package/bundle/typescript/src/commands/game/sideQuest/spells.d.ts +64 -0
  63. package/bundle/typescript/src/commands/game/sideQuest/spells.js +68 -0
  64. package/bundle/typescript/src/commands/game/sideQuest/spells.js.map +1 -0
  65. package/bundle/typescript/src/commands/game/sideQuest/types/save-file.d.ts +25 -2
  66. package/bundle/typescript/src/commands/game/sideQuest/ui.js +14 -0
  67. package/bundle/typescript/src/commands/game/sideQuest/ui.js.map +1 -1
  68. package/bundle/typescript/src/commands/game/sideQuest/utilities/alarmed-staff.d.ts +116 -0
  69. package/bundle/typescript/src/commands/game/sideQuest/utilities/alarmed-staff.js +127 -0
  70. package/bundle/typescript/src/commands/game/sideQuest/utilities/alarmed-staff.js.map +1 -0
  71. package/bundle/typescript/src/commands/game/sideQuest/utilities/catalog-data.d.ts +1 -1
  72. package/bundle/typescript/src/commands/game/sideQuest/utilities/catalog-data.js +123 -2
  73. package/bundle/typescript/src/commands/game/sideQuest/utilities/catalog-data.js.map +1 -1
  74. package/bundle/typescript/src/commands/game/sideQuest/utilities/catalog.d.ts +131 -2
  75. package/bundle/typescript/src/commands/game/sideQuest/utilities/catalog.js +170 -12
  76. package/bundle/typescript/src/commands/game/sideQuest/utilities/catalog.js.map +1 -1
  77. package/bundle/typescript/src/commands/game/sideQuest/utilities/cloud-saves.d.ts +139 -1
  78. package/bundle/typescript/src/commands/game/sideQuest/utilities/cloud-saves.js +307 -5
  79. package/bundle/typescript/src/commands/game/sideQuest/utilities/cloud-saves.js.map +1 -1
  80. package/bundle/typescript/src/commands/game/sideQuest/utilities/persistence.d.ts +38 -0
  81. package/bundle/typescript/src/commands/game/sideQuest/utilities/persistence.js +106 -0
  82. package/bundle/typescript/src/commands/game/sideQuest/utilities/persistence.js.map +1 -1
  83. package/bundle/typescript/src/commands/game/sideQuest/utilities/session-lock.js +19 -3
  84. package/bundle/typescript/src/commands/game/sideQuest/utilities/session-lock.js.map +1 -1
  85. package/bundle/typescript/src/commands/game/sideQuest/utilities/sin.js +1 -1
  86. package/bundle/typescript/src/commands/game/sideQuest/utilities/sin.js.map +1 -1
  87. package/bundle/typescript/src/commands/game/sideQuest/utilities/web-character-generator.d.ts +22 -0
  88. package/bundle/typescript/src/commands/game/sideQuest/utilities/web-character-generator.js +27 -0
  89. package/bundle/typescript/src/commands/game/sideQuest/utilities/web-character-generator.js.map +1 -1
  90. package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js +63 -30
  91. package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js.map +1 -1
  92. package/package.json +1 -1
@@ -4,7 +4,15 @@ export declare function authToken(): string | undefined;
4
4
  * the token) -- the value runner saves BIND to (account-binding
5
5
  * ruling). Never printed; never leaves the machine. */
6
6
  export declare function accountUserId(): string | undefined;
7
- export type CloudResult = 'ok' | 'unauthorized' | 'offline';
7
+ /**
8
+ * `stale` is the server's monotonic guard answering 409: the stored save
9
+ * is NEWER than the one we pushed (§8). Distinct from 'offline' because
10
+ * the two demand opposite responses -- an outage means retry, a stale
11
+ * means STOP pushing and let a human reconcile at the next launch.
12
+ * Folding it into 'offline' would make this client retry forever against
13
+ * a server that is right to refuse it.
14
+ */
15
+ export type CloudResult = 'ok' | 'unauthorized' | 'offline' | 'stale';
8
16
  export interface ICloudSummary {
9
17
  slug: string;
10
18
  playerName: string;
@@ -60,3 +68,133 @@ export declare function reconcile(local: {
60
68
  } | undefined, cloud: {
61
69
  savedAt: string;
62
70
  } | undefined): ReconcileVerdict;
71
+ /**
72
+ * THE COALESCING SINGLE-FLIGHT PUSH QUEUE (server-only storage, PR1).
73
+ *
74
+ * A bound runner's save lives on the server; a beat writes the SPILL
75
+ * synchronously (persistence.spillPathFor) and then enqueues here. Two
76
+ * properties, and both are about not lying to the player:
77
+ *
78
+ * SINGLE-FLIGHT: one request in the air at a time. Overlapping pushes
79
+ * arrive out of order, and last-writer-wins on an out-of-order pair
80
+ * means a later beat can be overwritten by an earlier one that happened
81
+ * to land second -- silently, and only visible as lost progress.
82
+ *
83
+ * COALESCING: the queue holds exactly ONE pending save, the newest.
84
+ * Intermediate snapshots are obsolete the moment a newer one exists, so
85
+ * a slow link must not build a backlog it then has to replay. Play
86
+ * generates beats faster than a bad connection drains them; a FIFO here
87
+ * would guarantee the queue never empties.
88
+ *
89
+ * The spill is what makes both safe: nothing is dropped, because
90
+ * whatever is not confirmed is still on disk.
91
+ */
92
+ /**
93
+ * How a queued save reaches the server. A PARAMETER rather than a hard
94
+ * call to pushSave, because the queue's job is ORDERING and the
95
+ * transport is not part of it -- and because an ES module's exports are
96
+ * read-only, so a test cannot substitute pushSave any other way. The
97
+ * seam follows the shape this codebase already uses for narrow
98
+ * dependencies (IEphemeralHost, attachInputHistory's `render`).
99
+ */
100
+ export type PushFn = (saveFilePath: string, save: ISaveFileV1) => Promise<CloudResult>;
101
+ /** Test seam: the queue is module state, and a suite that ran two cases
102
+ * against one dirty queue would be testing the previous test. */
103
+ export declare function _resetPushQueue(): void;
104
+ /**
105
+ * Enqueue a bound save. Returns immediately -- requestSave's contract is
106
+ * synchronous (game.ts) and the spill has already been written by the
107
+ * time this is called, so nothing here is allowed to block a beat.
108
+ */
109
+ export declare function enqueueBoundPush(saveFilePath: string, save: ISaveFileV1, spillPath?: string, push?: PushFn): void;
110
+ /**
111
+ * Drain to completion -- the QUIT SEAL and the job-accept handoff.
112
+ *
113
+ * These are the two places where "eventually" is not good enough: quit
114
+ * ends the process (nothing later will retry), and accepting a job hands
115
+ * this character to a shared run that loads it from the SERVER, so an
116
+ * unpushed beat is a stale snapshot the whole table then plays against.
117
+ * That race exists today and this is what closes it.
118
+ *
119
+ * Resolves true when the server has the newest save. False means the
120
+ * spill stands and the next launch will carry it.
121
+ */
122
+ export declare function flushPushQueue(): Promise<boolean>;
123
+ /** True while a bound save has not reached the server. */
124
+ export declare function hasPendingPush(): boolean;
125
+ /**
126
+ * Remove a spill whose contents the server has confirmed. Guarded on
127
+ * savedAt: a spill rewritten by a newer beat between the push and the
128
+ * confirmation is NOT the file we just uploaded, and deleting it would
129
+ * throw away the only copy of that beat.
130
+ */
131
+ export declare function clearSpill(spillPath: string, confirmedSavedAt: string): void;
132
+ /**
133
+ * Write the spill, SYNCHRONOUSLY, and never throw.
134
+ *
135
+ * requestSave's signature is synchronous and that is load-bearing: it is
136
+ * called from `process.on('exit')`, where nothing asynchronous can run
137
+ * at all. For a bound runner the spill write IS the durability
138
+ * guarantee at that moment -- the push is best-effort and the process is
139
+ * already leaving.
140
+ *
141
+ * SWALLOWS ITS ERRORS ON PURPOSE, and this is the one place where that
142
+ * is right rather than lazy: a full disk or a permissions fault during
143
+ * the exit hook must not turn a clean quit into a crash on the way out.
144
+ * The player would lose the beat either way; throwing loses the exit
145
+ * too, and prints a stack trace over their last screen.
146
+ */
147
+ export declare function writeSpill(spillPath: string, save: ISaveFileV1): boolean;
148
+ /**
149
+ * ONE SESSION PER RUNNER, ACROSS MACHINES (§8).
150
+ *
151
+ * The local `.lock` already stops two terminals on one box. It cannot
152
+ * see another machine, and without this a second laptop playing the same
153
+ * bound runner is two sessions pushing to one slot -- last-push-wins,
154
+ * with the loser's evening silently gone.
155
+ *
156
+ * TRANSITIONAL TOLERANCE, and it is deliberately loud in the code so it
157
+ * gets removed: the server half of this contract does not exist yet
158
+ * (rollout step 1 ships it; this is step 2). A 404 therefore means
159
+ * "this server does not know about leases", NOT "the lease is free" --
160
+ * and the honest reading of an unimplemented guard is to proceed
161
+ * without it, exactly as this client did before the guard existed.
162
+ *
163
+ * REMOVE THIS BRANCH once the server contract is deployed everywhere.
164
+ * Left in place it would mask a genuinely missing endpoint forever,
165
+ * which is the same shape as the compat branch that hid the review
166
+ * queue's blindness for a day.
167
+ */
168
+ export type LeaseResult = {
169
+ ok: true;
170
+ ttlMs?: number;
171
+ } | {
172
+ ok: false;
173
+ reason: 'held';
174
+ heldBy?: string;
175
+ since?: string;
176
+ } | {
177
+ ok: false;
178
+ reason: 'offline' | 'unauthorized' | 'unsupported';
179
+ };
180
+ export declare const acquireLease: (slug: string, sessionId: string) => Promise<LeaseResult>;
181
+ export declare const releaseLease: (slug: string, sessionId: string) => Promise<LeaseResult>;
182
+ /**
183
+ * Whether a lease failure should STOP the boot.
184
+ *
185
+ * ONLY a held lease does. Offline, unauthorized and unsupported all mean
186
+ * "we could not ask", and refusing to play because the lock server was
187
+ * unreachable would turn every outage into a lockout -- which is the
188
+ * opposite of ruling 2 (an outage degrades to the spill, it does not end
189
+ * the session). A HELD lease is the one case where we know the answer
190
+ * and the answer is no.
191
+ */
192
+ export declare function leaseRefusesBoot(result: LeaseResult): boolean;
193
+ /**
194
+ * Keep the lease alive while playing. Renewal FAILURES ARE TOLERATED:
195
+ * a dropped renew during an outage must not kill a live session -- the
196
+ * server's TTL expires it on its own, and a crash is exactly what the
197
+ * TTL is for.
198
+ */
199
+ export declare function startLeaseRenewal(slug: string, sessionId: string, everyMs?: number): void;
200
+ export declare function stopLeaseRenewal(): void;
@@ -6,11 +6,33 @@ import * as https from 'https';
6
6
  import { Logger } from './logger.js';
7
7
  import { saveSlug, readSave, writeSaveAtomic, tombstonePathFor } from './persistence.js';
8
8
  /**
9
- * CLOUD MIRROR for the save slots (rulings: LOCAL-FIRST -- the local
10
- * file is always written and always authoritative for play; the cloud
11
- * at www.maka-cli.com is a mirror kept fresh when the user is logged in
12
- * via `maka login`. Offline or logged out, everything here degrades to
13
- * a silent no-op and the game never notices).
9
+ * CLOUD STORAGE for the save slots, and the header this file carried
10
+ * for most of its life is no longer true of half its callers.
11
+ *
12
+ * IT SAID "LOCAL-FIRST -- the local file is always written and always
13
+ * authoritative for play; the cloud is a mirror". That still describes
14
+ * an ANONYMOUS runner exactly, and anonymous is deliberately untouched
15
+ * by all of this. It does NOT describe a BOUND one: the user's ruling
16
+ * is that an account-bound character lives ONLY on the server, because
17
+ * storing them twice produced a class of real bugs -- a deleted
18
+ * character resurrected from the cloud copy, a shared run loading a
19
+ * stale snapshot because the push was never awaited, and silent
20
+ * newest-wins resolution of divergences nobody was told about.
21
+ *
22
+ * So the model is now split, and every branch gates on bound:
23
+ *
24
+ * ANONYMOUS -- local file, authoritative, never leaves the machine.
25
+ * BOUND -- the server is the save. A synchronous local SPILL
26
+ * (persistence.spillPathFor) is a crash journal, not a
27
+ * second home: it exists only between a beat and its
28
+ * confirmed upload, and the next launch uploads and
29
+ * deletes it. Bound is online-only by ruling; an outage
30
+ * mid-session degrades to the spill rather than ending
31
+ * the session.
32
+ *
33
+ * PR1 NOTE: bound runners still write `<slug>.json` as well, so this
34
+ * change is a revert-trivial superset of the old behaviour. PR2 removes
35
+ * that write once the server contract is deployed.
14
36
  *
15
37
  * Auth rides the same rails as login/logout: the Meteor resume token
16
38
  * from global-config.json's `token` property, sent as `x-auth-token`.
@@ -127,6 +149,15 @@ export async function pushSave(saveFilePath, save) {
127
149
  noteUnauthorized();
128
150
  return 'unauthorized';
129
151
  }
152
+ // THE MONOTONIC GUARD (§8): the stored save is newer than ours, so
153
+ // this push would move the runner BACKWARDS. Reported distinctly
154
+ // because retrying it is exactly the wrong response -- see
155
+ // CloudResult. An equal savedAt is idempotent and answers 200, so a
156
+ // 409 always means genuinely behind.
157
+ if (res.statusCode === 409) {
158
+ logger.write(`Cloud sync: push refused as stale (server copy is newer than ${save.savedAt}).`);
159
+ return 'stale';
160
+ }
130
161
  logger.write(`Cloud sync: push got ${res.statusCode} -- staying local.`);
131
162
  return 'offline';
132
163
  }
@@ -275,4 +306,275 @@ export function reconcile(local, cloud) {
275
306
  return 'pull-cloud';
276
307
  return 'diverged';
277
308
  }
309
+ let pending;
310
+ let inFlight = false;
311
+ let retryTimer;
312
+ /** One notice per OUTAGE, not per failed beat -- see noteOutage. */
313
+ let outageAnnounced = false;
314
+ /** Set when a 409 says the server holds something newer than us. */
315
+ let staleAnnounced = false;
316
+ /** Retry cadence when the grid is down. Unref'd: a pending retry must
317
+ * never hold the process open at exit. */
318
+ const RETRY_MS = 60_000;
319
+ function noteOutage() {
320
+ if (outageAnnounced)
321
+ return;
322
+ outageAnnounced = true;
323
+ const logger = Logger.getInstance();
324
+ const line = `The grid dropped -- your progress is recording locally and will upload automatically next launch.`;
325
+ if (logger.hasScreen())
326
+ logger.logWithColor(line, 'yellow');
327
+ else
328
+ logger.write(`Cloud sync: outage -- ${line}`);
329
+ }
330
+ function noteRecovered() {
331
+ if (!outageAnnounced)
332
+ return;
333
+ outageAnnounced = false;
334
+ const logger = Logger.getInstance();
335
+ const line = `The grid's back -- your progress is synced.`;
336
+ if (logger.hasScreen())
337
+ logger.logWithColor(line, 'green');
338
+ else
339
+ logger.write('Cloud sync: recovered.');
340
+ }
341
+ /**
342
+ * A 409 means the SERVER is ahead of us: another machine pushed a newer
343
+ * save for this runner. Never overwrite play state from here -- this
344
+ * process is mid-session and its player is looking at the world it
345
+ * believes in. The spill survives, the warning fires once, and the
346
+ * launcher reconciles at the next launch where a human can be asked.
347
+ */
348
+ function noteStale() {
349
+ if (staleAnnounced)
350
+ return;
351
+ staleAnnounced = true;
352
+ const logger = Logger.getInstance();
353
+ const line = `This runner was saved from somewhere else more recently. Your progress is being kept locally -- sort it out at the next launch.`;
354
+ if (logger.hasScreen())
355
+ logger.logWithColor(line, 'yellow');
356
+ else
357
+ logger.write('Cloud sync: 409 stale -- server copy is newer.');
358
+ }
359
+ /** Test seam: the queue is module state, and a suite that ran two cases
360
+ * against one dirty queue would be testing the previous test. */
361
+ export function _resetPushQueue() {
362
+ pending = undefined;
363
+ inFlight = false;
364
+ if (retryTimer)
365
+ clearTimeout(retryTimer);
366
+ retryTimer = undefined;
367
+ outageAnnounced = false;
368
+ staleAnnounced = false;
369
+ }
370
+ function armRetry() {
371
+ if (retryTimer || !pending)
372
+ return;
373
+ retryTimer = setTimeout(() => {
374
+ retryTimer = undefined;
375
+ void drainQueue();
376
+ }, RETRY_MS);
377
+ // A save waiting to retry must not keep the game alive at exit; the
378
+ // spill on disk is the guarantee, not this timer.
379
+ retryTimer.unref?.();
380
+ }
381
+ async function drainQueue() {
382
+ if (inFlight)
383
+ return;
384
+ const next = pending;
385
+ if (!next)
386
+ return;
387
+ pending = undefined;
388
+ inFlight = true;
389
+ try {
390
+ const res = await next.push(next.saveFilePath, next.save);
391
+ if (res === 'ok') {
392
+ noteRecovered();
393
+ // THE SPILL DIES ONLY ON A CONFIRMED PUSH OF THIS EXACT SAVE.
394
+ // Deleting it on any 200 would drop a NEWER beat's journal when an
395
+ // older push confirmed late -- the out-of-order case single-flight
396
+ // mostly prevents and this makes impossible.
397
+ if (next.spillPath && !pending)
398
+ clearSpill(next.spillPath, next.save.savedAt);
399
+ }
400
+ else if (res === 'stale') {
401
+ noteStale();
402
+ }
403
+ else if (res !== 'unauthorized') {
404
+ noteOutage();
405
+ // Put it back ONLY if nothing newer arrived while we were away.
406
+ if (!pending)
407
+ pending = next;
408
+ }
409
+ }
410
+ finally {
411
+ inFlight = false;
412
+ }
413
+ if (pending) {
414
+ if (outageAnnounced || staleAnnounced)
415
+ armRetry();
416
+ else
417
+ await drainQueue();
418
+ }
419
+ }
420
+ /**
421
+ * Enqueue a bound save. Returns immediately -- requestSave's contract is
422
+ * synchronous (game.ts) and the spill has already been written by the
423
+ * time this is called, so nothing here is allowed to block a beat.
424
+ */
425
+ export function enqueueBoundPush(saveFilePath, save, spillPath, push = pushSave) {
426
+ pending = { saveFilePath, save, spillPath, push };
427
+ void drainQueue();
428
+ }
429
+ /**
430
+ * Drain to completion -- the QUIT SEAL and the job-accept handoff.
431
+ *
432
+ * These are the two places where "eventually" is not good enough: quit
433
+ * ends the process (nothing later will retry), and accepting a job hands
434
+ * this character to a shared run that loads it from the SERVER, so an
435
+ * unpushed beat is a stale snapshot the whole table then plays against.
436
+ * That race exists today and this is what closes it.
437
+ *
438
+ * Resolves true when the server has the newest save. False means the
439
+ * spill stands and the next launch will carry it.
440
+ */
441
+ export async function flushPushQueue() {
442
+ if (retryTimer) {
443
+ clearTimeout(retryTimer);
444
+ retryTimer = undefined;
445
+ }
446
+ // Bounded: each pass either lands the newest save or fails, and a
447
+ // failure stops the loop rather than spinning on a dead link.
448
+ for (let i = 0; i < 3 && pending; i++) {
449
+ const before = pending;
450
+ await drainQueue();
451
+ if (pending === before)
452
+ break;
453
+ }
454
+ return pending === undefined;
455
+ }
456
+ /** True while a bound save has not reached the server. */
457
+ export function hasPendingPush() {
458
+ return pending !== undefined;
459
+ }
460
+ /**
461
+ * Remove a spill whose contents the server has confirmed. Guarded on
462
+ * savedAt: a spill rewritten by a newer beat between the push and the
463
+ * confirmation is NOT the file we just uploaded, and deleting it would
464
+ * throw away the only copy of that beat.
465
+ */
466
+ export function clearSpill(spillPath, confirmedSavedAt) {
467
+ try {
468
+ if (!fs.existsSync(spillPath))
469
+ return;
470
+ const onDisk = readSave(spillPath);
471
+ if (onDisk.ok && onDisk.save.savedAt !== confirmedSavedAt)
472
+ return;
473
+ fs.rmSync(spillPath, { force: true });
474
+ Logger.getInstance().write(`Cloud sync: spill cleared (${confirmedSavedAt}).`);
475
+ }
476
+ catch (err) {
477
+ // A spill we cannot delete is a spill that gets uploaded again next
478
+ // launch and found to be identical -- harmless. Never fatal.
479
+ Logger.getInstance().write(`Cloud sync: could not clear spill -- ${err.message ?? err}`);
480
+ }
481
+ }
482
+ /**
483
+ * Write the spill, SYNCHRONOUSLY, and never throw.
484
+ *
485
+ * requestSave's signature is synchronous and that is load-bearing: it is
486
+ * called from `process.on('exit')`, where nothing asynchronous can run
487
+ * at all. For a bound runner the spill write IS the durability
488
+ * guarantee at that moment -- the push is best-effort and the process is
489
+ * already leaving.
490
+ *
491
+ * SWALLOWS ITS ERRORS ON PURPOSE, and this is the one place where that
492
+ * is right rather than lazy: a full disk or a permissions fault during
493
+ * the exit hook must not turn a clean quit into a crash on the way out.
494
+ * The player would lose the beat either way; throwing loses the exit
495
+ * too, and prints a stack trace over their last screen.
496
+ */
497
+ export function writeSpill(spillPath, save) {
498
+ try {
499
+ writeSaveAtomic(spillPath, save);
500
+ return true;
501
+ }
502
+ catch (err) {
503
+ Logger.getInstance().write(`Cloud sync: spill write FAILED (${err.message ?? err}).`);
504
+ return false;
505
+ }
506
+ }
507
+ async function leaseCall(slug, sessionId, action) {
508
+ const token = authToken();
509
+ if (!token)
510
+ return { ok: false, reason: 'unauthorized' };
511
+ try {
512
+ const res = await request('POST', `/${API_BASE}/${slug}/lease`, token, { sessionId, action });
513
+ if (res.statusCode === 200) {
514
+ const body = parseLease(res.data);
515
+ return { ok: true, ttlMs: body?.ttlMs };
516
+ }
517
+ if (res.statusCode === 401) {
518
+ noteUnauthorized();
519
+ return { ok: false, reason: 'unauthorized' };
520
+ }
521
+ if (res.statusCode === 409) {
522
+ const body = parseLease(res.data);
523
+ return { ok: false, reason: 'held', heldBy: body?.heldBy, since: body?.since };
524
+ }
525
+ // See the transitional note above: an unimplemented endpoint is not
526
+ // a free lease and is not an outage either.
527
+ if (res.statusCode === 404) {
528
+ Logger.getInstance().write(`Lease: server has no lease endpoint -- proceeding without cross-machine locking.`);
529
+ return { ok: false, reason: 'unsupported' };
530
+ }
531
+ return { ok: false, reason: 'offline' };
532
+ }
533
+ catch {
534
+ return { ok: false, reason: 'offline' };
535
+ }
536
+ }
537
+ function parseLease(raw) {
538
+ try {
539
+ const parsed = JSON.parse(raw);
540
+ const body = (parsed?.data ?? parsed);
541
+ return body;
542
+ }
543
+ catch {
544
+ return undefined;
545
+ }
546
+ }
547
+ export const acquireLease = (slug, sessionId) => leaseCall(slug, sessionId, 'acquire');
548
+ export const releaseLease = (slug, sessionId) => leaseCall(slug, sessionId, 'release');
549
+ /**
550
+ * Whether a lease failure should STOP the boot.
551
+ *
552
+ * ONLY a held lease does. Offline, unauthorized and unsupported all mean
553
+ * "we could not ask", and refusing to play because the lock server was
554
+ * unreachable would turn every outage into a lockout -- which is the
555
+ * opposite of ruling 2 (an outage degrades to the spill, it does not end
556
+ * the session). A HELD lease is the one case where we know the answer
557
+ * and the answer is no.
558
+ */
559
+ export function leaseRefusesBoot(result) {
560
+ return result.ok === false && result.reason === 'held';
561
+ }
562
+ let renewTimer;
563
+ /**
564
+ * Keep the lease alive while playing. Renewal FAILURES ARE TOLERATED:
565
+ * a dropped renew during an outage must not kill a live session -- the
566
+ * server's TTL expires it on its own, and a crash is exactly what the
567
+ * TTL is for.
568
+ */
569
+ export function startLeaseRenewal(slug, sessionId, everyMs = 30_000) {
570
+ stopLeaseRenewal();
571
+ renewTimer = setInterval(() => { void leaseCall(slug, sessionId, 'renew'); }, everyMs);
572
+ // Never hold the process open for a lock we are about to release.
573
+ renewTimer.unref?.();
574
+ }
575
+ export function stopLeaseRenewal() {
576
+ if (renewTimer)
577
+ clearInterval(renewTimer);
578
+ renewTimer = undefined;
579
+ }
278
580
  //# sourceMappingURL=cloud-saves.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cloud-saves.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/utilities/cloud-saves.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cloud-saves.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/utilities/cloud-saves.ts"],"names":[],"mappings":"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"}
@@ -21,6 +21,44 @@ export declare function savePathFor(dir: string, playerName: string): string;
21
21
  * copy couldn't be deleted (offline) -- the launcher honors it later
22
22
  * instead of resurrecting the dead from the cloud. */
23
23
  export declare function tombstonePathFor(dir: string, playerName: string): string;
24
+ /**
25
+ * THE SPILL: a bound runner's crash journal, NOT a second home.
26
+ *
27
+ * A bound character's save lives on the server (user ruling: bound is
28
+ * online-only). The spill is what keeps that honest when the grid drops
29
+ * mid-session -- every beat still writes here synchronously, and the
30
+ * NEXT launch uploads it and deletes it. It never outlives one
31
+ * successful sync, which is the whole difference between a journal and
32
+ * the dual storage this change exists to remove.
33
+ *
34
+ * `.spill`, DELIBERATELY NOT `.json`, and that extension is the entire
35
+ * mechanism keeping it out of the menu: listSaves filters on `.json`,
36
+ * so a spill can never be offered as a slot to load. Naming it
37
+ * `<slug>.spill.json` would have put a half-written recovery file in
38
+ * front of the player as a playable character.
39
+ *
40
+ * Same slug as the save and the tombstone, so all three names for one
41
+ * runner are derivable from the runner and from nothing else.
42
+ */
43
+ export declare function spillPathFor(dir: string, playerName: string): string;
44
+ /**
45
+ * THE LOCK ANCHOR: the extensionless path all of a runner's sidecar
46
+ * files hang off.
47
+ *
48
+ * session-lock.ts builds `<slot>.lock` by stripping `.json` off the save
49
+ * path, which quietly assumes the save FILE exists to derive a name
50
+ * from. For a bound runner after PR2 it will not -- their save lives on
51
+ * the server -- and the lock would have had nowhere to hang.
52
+ *
53
+ * Anchoring on the SLUG instead makes the lock a property of the
54
+ * RUNNER rather than of a file that may or may not be on this disk.
55
+ * `lockPathFor(lockAnchorFor(dir, name))` is byte-identical to today's
56
+ * `lockPathFor(savePathFor(dir, name))` -- the anchor simply has no
57
+ * `.json` for the strip to remove -- so no existing lock is orphaned and
58
+ * a half-upgraded machine cannot end up with two lock paths for one
59
+ * runner, which would be one lock each and no exclusion at all.
60
+ */
61
+ export declare function lockAnchorFor(dir: string, playerName: string): string;
24
62
  /**
25
63
  * Atomic-enough for one slot: write a .tmp beside the target, then
26
64
  * rename over it. A crash mid-write leaves a stale .tmp, never a