amalgm 0.1.213 → 0.1.215

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "amalgm",
3
- "version": "0.1.213",
3
+ "version": "0.1.215",
4
4
  "description": "Amalgm local computer runtime: login, MCP, chat, events, previews, and tunnels.",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,
@@ -243,6 +243,37 @@ test('a clean losing commit travels as parked metadata on a no-op checkpoint', (
243
243
  assert.deepEqual(checkpoint.parked, parked);
244
244
  });
245
245
 
246
+ test('only this machine keeps announcing its parked commits', () => {
247
+ const baseOid = 'a'.repeat(40);
248
+ const localOid = 'b'.repeat(40);
249
+ const peerOid = 'c'.repeat(40);
250
+ const pendingOid = 'd'.repeat(40);
251
+ const existing = {
252
+ branch: 'main',
253
+ baseOid,
254
+ parked: [{ oid: localOid, objects: { kind: 'pending' } }],
255
+ };
256
+ const reduced = {
257
+ parked: [
258
+ { oid: localOid, version: 10, objects: { kind: 'pending' } },
259
+ { oid: peerOid, version: 11, objects: { kind: 'bundle' } },
260
+ { oid: pendingOid, objects: { kind: 'pending' } },
261
+ ],
262
+ };
263
+ const card = { head: { branch: 'main', oid: baseOid } };
264
+
265
+ assert.deepEqual(
266
+ _test.localParkedEntries(existing, reduced, card).map((entry) => entry.oid),
267
+ [localOid, pendingOid],
268
+ );
269
+ assert.deepEqual(
270
+ _test.localParkedEntries(existing, reduced, {
271
+ head: { branch: 'main', oid: 'e'.repeat(40) },
272
+ }).map((entry) => entry.oid),
273
+ [pendingOid],
274
+ );
275
+ });
276
+
246
277
  test('a server rail number does not turn the same parked checkpoint into new work', () => {
247
278
  const value = { revision: null, indexDiff: '', worktreeDiff: '' };
248
279
  const checkpoint = {
@@ -28,6 +28,7 @@ const {
28
28
  hydrateRepo,
29
29
  localCardMayMaterialize,
30
30
  materializeRepo,
31
+ parkedForState,
31
32
  pathForRepo,
32
33
  readRepoState,
33
34
  reduceCheckpoint,
@@ -175,6 +176,17 @@ test('a ready parked bundle never regresses to pending', () => {
175
176
  assert.equal(plan.parked[0].objects.kind, 'bundle');
176
177
  });
177
178
 
179
+ test('an unpublished local parked commit stays active until the rail records it', () => {
180
+ const oid = 'f'.repeat(40);
181
+ const local = { oid, objects: { kind: 'bundle', checksum: 'local' } };
182
+ assert.deepEqual(parkedForState([local], [], []), [local]);
183
+ assert.deepEqual(parkedForState([local], [{ ...local, version: 7 }], []), [{
184
+ ...local,
185
+ version: 7,
186
+ }]);
187
+ assert.deepEqual(parkedForState([{ ...local, version: 7 }], [], []), []);
188
+ });
189
+
178
190
  test('a stale lower rail card cannot roll back a newer branch and commit', () => {
179
191
  const newer = card('/newer', 'b'.repeat(40), 12);
180
192
  newer.head.branch = 'feature';
@@ -507,6 +519,32 @@ test('a losing commit is parked, the winning card lands exactly, and losing work
507
519
  assert.equal(fs.readFileSync(path.join(repo, 'local-dirty.txt'), 'utf8'), 'also uncommitted\n');
508
520
  assert.equal((await git(repo, 'status', '--porcelain')).trim().length > 0, true);
509
521
  assert.deepEqual(readRepoState('root:test').parked.map((entry) => entry.oid), [losingOid]);
522
+
523
+ const sharedParked = readRepoState('root:test').parked.map((entry) => ({
524
+ ...entry,
525
+ version: 2,
526
+ }));
527
+ await materializeRepo(card(repo, winningOid, 2), {
528
+ repoKey: 'root:test',
529
+ card: winningCard,
530
+ transitions: [],
531
+ parked: sharedParked,
532
+ });
533
+
534
+ await git(repo, 'add', '.');
535
+ await git(repo, 'commit', '-m', 'fold parked work');
536
+ const foldedOid = (await git(repo, 'rev-parse', 'HEAD')).trim();
537
+ const foldedCard = card(repo, foldedOid, 3);
538
+ const folded = await materializeRepo(foldedCard, {
539
+ repoKey: 'root:test',
540
+ card: foldedCard,
541
+ transitions: [],
542
+ parked: [],
543
+ });
544
+
545
+ assert.equal(folded.state, 'in-sync');
546
+ assert.deepEqual(readRepoState('root:test').parked, []);
547
+ assert.equal((await git(repo, 'rev-parse', `refs/amalgm/parked/${losingOid}`)).trim(), losingOid);
510
548
  });
511
549
 
512
550
  test('rail-parked peer commits become one staged checkpoint on every machine', async () => {
@@ -120,6 +120,15 @@ test('only a value different from both the materialized baseline and the rail is
120
120
  branches: [{ name: 'main', oid: oidC }],
121
121
  };
122
122
  assert.equal(hasLocalContribution(local, remoteAdvance, baseline), false);
123
+ assert.equal(hasLocalContribution(local, remoteAdvance, baseline, {
124
+ checkpoint: 'repo-checkpoint@7',
125
+ machine: 'machine-a',
126
+ branch: 'main',
127
+ baseOid: oidA,
128
+ from: { revision: null, indexDiff: '', worktreeDiff: '' },
129
+ to: { revision: 'old-work', indexDiff: '', worktreeDiff: 'patch' },
130
+ parked: [],
131
+ }), false);
123
132
  assert.equal(hasLocalContribution(
124
133
  {
125
134
  head: { branch: 'main', oid: oidB, detached: false },
@@ -157,6 +157,17 @@ function checkpointForSharedState(existing, {
157
157
  };
158
158
  }
159
159
 
160
+ function localParkedEntries(existing, reduced, card) {
161
+ const held = existing?.baseOid === card.head?.oid
162
+ && existing.branch === card.head?.branch
163
+ ? existing.parked || []
164
+ : [];
165
+ const unpublished = (reduced?.parked || []).filter((entry) => (
166
+ !Number.isInteger(entry.version) || entry.version < 1
167
+ ));
168
+ return [...new Map([...held, ...unpublished].map((entry) => [entry.oid, entry])).values()];
169
+ }
170
+
160
171
  function readCheckpointValue(baseOid, value) {
161
172
  let indexDiff = typeof value?.indexDiff === 'string' ? value.indexDiff : '';
162
173
  let worktreeDiff = typeof value?.worktreeDiff === 'string' ? value.worktreeDiff : '';
@@ -228,7 +239,7 @@ async function publishPass(replicaId = null) {
228
239
  const localRevision = revisionOf(card.head.oid, captured.indexDiff, captured.worktreeDiff);
229
240
  const file = checkpointFile(machine, repoKey);
230
241
  const existing = readCheckpoint(machine, repoKey);
231
- const parked = await Promise.all((reduced.parked || []).map(async (entry) => ({
242
+ const parked = await Promise.all(localParkedEntries(existing, reduced, card).map(async (entry) => ({
232
243
  ...entry,
233
244
  objects: await require('./objects').bundleSourceFor(card.path, repoKey, entry.oid),
234
245
  })));
@@ -393,6 +404,7 @@ module.exports = {
393
404
  checkpointBaseReady,
394
405
  checkpointForSharedState,
395
406
  checkpointMayPublish,
407
+ localParkedEntries,
396
408
  },
397
409
  CHECKPOINT_CONTRACT,
398
410
  MAX_INLINE_DIFF_BYTES,
@@ -176,6 +176,18 @@ function uniqueParked(entries) {
176
176
  return order.map((oid) => byOid.get(oid));
177
177
  }
178
178
 
179
+ function parkedForState(previous, shared, discovered) {
180
+ const sharedOids = new Set((shared || []).map((entry) => entry.oid));
181
+ const unpublished = (previous || []).filter((entry) => (
182
+ !validVersion(entry.version) && !sharedOids.has(entry.oid)
183
+ ));
184
+ return uniqueParked([
185
+ ...(shared || []),
186
+ ...unpublished,
187
+ ...(discovered || []),
188
+ ]);
189
+ }
190
+
179
191
  async function obtainCardObjects(localCard, targetCard) {
180
192
  const oid = targetCard.head?.oid;
181
193
  if (!oid || await hasCommit(localCard.path, oid)) return { state: 'ready' };
@@ -512,11 +524,11 @@ async function materializeRepo(localCardInput, plan) {
512
524
  ? await refreshRepoCard(refreshed.replica) || refreshed
513
525
  : refreshed;
514
526
  const previous = readRepoState(plan.repoKey);
515
- const parked = uniqueParked([
516
- ...(previous?.parked || []),
517
- ...(plan.parked || []),
518
- ...(cardResult.parked || []),
519
- ]);
527
+ const parked = parkedForState(
528
+ previous?.parked,
529
+ plan.parked,
530
+ cardResult.parked,
531
+ );
520
532
  const parkedWaiting = await materializeParked(localCard, parked);
521
533
  const planParked = new Set((plan.parked || []).map((entry) => entry.oid));
522
534
  const requiredParkedWaiting = parkedWaiting.filter((entry) => planParked.has(entry.oid));
@@ -785,6 +797,7 @@ module.exports = {
785
797
  localCardMayMaterialize,
786
798
  materializeRepo,
787
799
  pathForRepo,
800
+ parkedForState,
788
801
  readRepoState,
789
802
  reduceCheckpoint,
790
803
  reduceNow,
@@ -260,7 +260,8 @@ function hasLocalContribution(card, plan, baseline, checkpoint = null, previousC
260
260
  }
261
261
 
262
262
  if (
263
- checkpoint
263
+ onRail
264
+ && checkpoint
264
265
  && checkpoint.baseOid === card.head?.oid
265
266
  && checkpoint.branch === card.head?.branch
266
267
  ) {