@pygmalionjs/pygmalion 0.6.34 → 0.6.35

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.
@@ -31,17 +31,30 @@ export interface MirrorGateStatus {
31
31
  export interface IdleMirrorSourceStatus extends MirrorGateStatus {
32
32
  sourceRef: string | null;
33
33
  }
34
+ /** One listed ref whose exact revision can start a lazy checkout. */
35
+ export interface IdleMirrorListedSourceRef {
36
+ name: string;
37
+ fullName?: string;
38
+ sourceRevision?: string;
39
+ }
40
+ /** The ref-list fields needed to resolve an idle named source. */
41
+ export interface IdleMirrorSourceRefs {
42
+ refs: readonly IdleMirrorListedSourceRef[];
43
+ defaultRef: string | null;
44
+ worktreeRef?: string | null;
45
+ }
34
46
  /**
35
47
  * Returns an immutable source revision that can safely create the first lazy
36
48
  * preview demand.
37
49
  *
38
50
  * An idle mirror has no checked-out `commit` yet. When it was configured with
39
51
  * a full Git object id, however, that ref already names the exact revision the
40
- * catalog endpoint will verify after preparation. Named refs, worktree mode,
41
- * and abbreviated ids can move or be ambiguous, so they remain pending until
42
- * the server reports the resolved commit.
52
+ * catalog endpoint will verify after preparation. A named ref can also create
53
+ * that first demand when the ref-list endpoint supplies its full object id.
54
+ * The abbreviated display commit is intentionally ignored: it can be
55
+ * ambiguous and cannot satisfy the exact source lease.
43
56
  */
44
- export declare function idleMirrorSourceRevision(status: IdleMirrorSourceStatus): string | null;
57
+ export declare function idleMirrorSourceRevision(status: IdleMirrorSourceStatus, sourceRefs?: IdleMirrorSourceRefs): string | null;
45
58
  export interface SettleMirrorStatusOptions<S extends MirrorGateStatus> {
46
59
  /** Status of the initial request; returned as-is when already settled. */
47
60
  initial: S;
@@ -22,7 +22,10 @@ export interface PygmalionDevMirrorStatus {
22
22
  /** One revision the mirror can be repointed at. */
23
23
  export interface PygmalionSourceRef {
24
24
  name: string;
25
+ /** Abbreviated commit used for compact branch-tip labels. */
25
26
  commit: string;
27
+ /** Full immutable object id used for preview and artifact identity. */
28
+ sourceRevision?: string;
26
29
  fullName: string;
27
30
  kind: 'local' | 'remote';
28
31
  }
@@ -350,15 +350,21 @@ function escapeRegExp(value) {
350
350
  * of asking for a ref string.
351
351
  */
352
352
  export async function listSourceRefs(repoRoot, remote = 'origin') {
353
- const format = '%(refname:short)%09%(objectname:short=8)%09%(refname)';
353
+ const format =
354
+ '%(refname:short)%09%(objectname:short=8)%09%(objectname)%09%(refname)';
354
355
  const read = async (...patterns) => {
355
356
  const raw = await git(repoRoot, 'for-each-ref', `--format=${format}`, ...patterns);
356
357
  if (!raw) return [];
357
358
  return raw
358
359
  .split('\n')
359
360
  .map((line) => line.split('\t'))
360
- .filter((parts) => parts.length === 3 && parts[0])
361
- .map(([name, commit, fullName]) => ({ name, commit, fullName }));
361
+ .filter((parts) => parts.length === 4 && parts[0])
362
+ .map(([name, commit, sourceRevision, fullName]) => ({
363
+ name,
364
+ commit,
365
+ sourceRevision,
366
+ fullName,
367
+ }));
362
368
  };
363
369
  const remotes = (await read(`refs/remotes/${remote}`))
364
370
  // `%(refname:short)` may abbreviate refs/remotes/origin/HEAD to just
@@ -375,15 +381,19 @@ export async function listSourceRefs(repoRoot, remote = 'origin') {
375
381
  // `dev@a0d5fdbf → 3e8cca5b`, an invitation to go backwards.
376
382
  const remoteTipPrefix = `refs/remotes/${remote}/`;
377
383
  const remoteTips = new Map(
378
- remotes.map((item) => [item.fullName.slice(remoteTipPrefix.length), item.commit]),
384
+ remotes.map((item) => [item.fullName.slice(remoteTipPrefix.length), item]),
379
385
  );
380
- const locals = (await read('refs/heads')).map((item) => ({
381
- ...item,
382
- // A branch the remote does not have resolves locally (the fetch fails and
383
- // becomes a warning), so its own tip is the honest answer there.
384
- commit: remoteTips.get(item.name) ?? item.commit,
385
- kind: 'local',
386
- }));
386
+ const locals = (await read('refs/heads')).map((item) => {
387
+ const remoteTip = remoteTips.get(item.name);
388
+ return {
389
+ ...item,
390
+ // A branch the remote does not have resolves locally (the fetch fails and
391
+ // becomes a warning), so its own tip is the honest answer there.
392
+ commit: remoteTip?.commit ?? item.commit,
393
+ sourceRevision: remoteTip?.sourceRevision ?? item.sourceRevision,
394
+ kind: 'local',
395
+ };
396
+ });
387
397
  const seen = new Set();
388
398
  return [...locals, ...remotes].filter((item) => {
389
399
  if (seen.has(item.name)) return false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pygmalionjs/pygmalion",
3
- "version": "0.6.34",
3
+ "version": "0.6.35",
4
4
  "description": "Code-backed DOM design sandbox and visual QA editor",
5
5
  "license": "UNLICENSED",
6
6
  "publishConfig": {