orizu 0.5.52 → 0.5.53

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 (65) hide show
  1. package/dist/auth-commands.js +2 -2
  2. package/dist/cli-console-output.d.ts +7 -1
  3. package/dist/cli-console-output.d.ts.map +1 -1
  4. package/dist/cli-console-output.js +16 -3
  5. package/dist/cli-stops.d.ts +14 -0
  6. package/dist/cli-stops.d.ts.map +1 -0
  7. package/dist/cli-stops.js +22 -0
  8. package/dist/egress-allowlist-cli.d.ts +29 -2
  9. package/dist/egress-allowlist-cli.d.ts.map +1 -1
  10. package/dist/egress-allowlist-cli.js +16 -89
  11. package/dist/egress-allowlist-workflow.d.ts +17 -0
  12. package/dist/egress-allowlist-workflow.d.ts.map +1 -0
  13. package/dist/egress-allowlist-workflow.js +183 -0
  14. package/dist/instruction-delivery.d.ts +4 -4
  15. package/dist/instruction-delivery.d.ts.map +1 -1
  16. package/dist/instruction-delivery.js +32 -46
  17. package/dist/instruction-prune.d.ts +24 -0
  18. package/dist/instruction-prune.d.ts.map +1 -0
  19. package/dist/instruction-prune.js +33 -0
  20. package/dist/instruction-set-sync/index.d.ts +0 -2
  21. package/dist/instruction-set-sync/index.d.ts.map +1 -1
  22. package/dist/instruction-set-sync/index.js +3 -36
  23. package/dist/instruction-set-update/index.d.ts +41 -3
  24. package/dist/instruction-set-update/index.d.ts.map +1 -1
  25. package/dist/instruction-set-update/index.js +156 -132
  26. package/dist/instruction-sets-cli.d.ts.map +1 -1
  27. package/dist/instruction-sets-cli.js +21 -2
  28. package/dist/instruction-sync-lock.d.ts +9 -0
  29. package/dist/instruction-sync-lock.d.ts.map +1 -0
  30. package/dist/instruction-sync-lock.js +24 -0
  31. package/dist/json-output-scrub.d.ts +3 -0
  32. package/dist/json-output-scrub.d.ts.map +1 -0
  33. package/dist/json-output-scrub.js +70 -0
  34. package/dist/one-request-write.d.ts.map +1 -1
  35. package/dist/one-request-write.js +2 -9
  36. package/dist/workbench-cli.d.ts +2 -1
  37. package/dist/workbench-cli.d.ts.map +1 -1
  38. package/dist/workbench-cli.js +79 -593
  39. package/dist/workbench-workflows.d.ts +56 -0
  40. package/dist/workbench-workflows.d.ts.map +1 -0
  41. package/dist/workbench-workflows.js +665 -0
  42. package/dist/workspace-sync-workflow.d.ts +115 -0
  43. package/dist/workspace-sync-workflow.d.ts.map +1 -0
  44. package/dist/workspace-sync-workflow.js +642 -0
  45. package/dist/workspace-sync.d.ts +45 -97
  46. package/dist/workspace-sync.d.ts.map +1 -1
  47. package/dist/workspace-sync.js +53 -494
  48. package/package.json +1 -1
  49. package/src/auth-commands.ts +2 -2
  50. package/src/cli-console-output.ts +16 -2
  51. package/src/cli-stops.ts +27 -0
  52. package/src/egress-allowlist-cli.ts +18 -90
  53. package/src/egress-allowlist-workflow.ts +198 -0
  54. package/src/instruction-delivery.ts +31 -47
  55. package/src/instruction-prune.ts +59 -0
  56. package/src/instruction-set-sync/index.ts +3 -43
  57. package/src/instruction-set-update/index.ts +173 -122
  58. package/src/instruction-sets-cli.ts +23 -2
  59. package/src/instruction-sync-lock.ts +27 -0
  60. package/src/json-output-scrub.ts +73 -0
  61. package/src/one-request-write.ts +2 -10
  62. package/src/workbench-cli.ts +83 -684
  63. package/src/workbench-workflows.ts +815 -0
  64. package/src/workspace-sync-workflow.ts +838 -0
  65. package/src/workspace-sync.ts +63 -630
@@ -1,11 +1,13 @@
1
+ import { join } from 'node:path';
1
2
  import { Cause, Effect, Exit } from 'effect';
3
+ import { runWithStops } from './cli-stops.js';
2
4
  import { authedFetch } from './http.js';
3
5
  import { responsePayload } from './json-response.js';
4
- import { stageSyncPayload, startSyncLockClaim, tryClaimSyncLock } from './instruction-set-sync/index.js';
5
- import { applyUpdate, lockedProfileIdentity, makeUpdatePlan, readUpdateLock } from './instruction-set-update/index.js';
6
- // Existing file steps throw plain errors; keep them as the failure value so the
7
- // CLI prints exactly the same message.
8
- const attempt = (operation) => Effect.try({ try: operation, catch: cause => cause });
6
+ import { stageSyncPayload } from './instruction-set-sync/index.js';
7
+ import { applyUpdate, lockedProfileIdentity, makeUpdatePlan, publishNoSyncUpdate, readUpdateLock } from './instruction-set-update/index.js';
8
+ import { attempt, holdSyncLock } from './instruction-sync-lock.js';
9
+ // Loaded only through `await import(...)` from instruction-sets-cli, so CLI
10
+ // startup and the published loader never load Effect.
9
11
  function readPayload(path, action) {
10
12
  return Effect.tryPromise({
11
13
  // The body stays unchecked here, as before: stageSyncPayload and makeUpdatePlan validate it.
@@ -14,51 +16,29 @@ function readPayload(path, action) {
14
16
  catch: cause => cause,
15
17
  });
16
18
  }
17
- // Waiting for another process's lock is the only interruptible part: nothing
18
- // is held yet. Publishing runs to completion once the lock is ours.
19
- function holdSyncLock(appRoot, use) {
20
- const acquire = Effect.gen(function* () {
21
- const claim = yield* attempt(() => startSyncLockClaim(appRoot));
22
- while (true) {
23
- const claimed = yield* attempt(() => tryClaimSyncLock(claim));
24
- if (typeof claimed === 'function')
25
- return claimed;
26
- yield* Effect.interruptible(Effect.sleep(claimed));
27
- }
28
- });
29
- return Effect.acquireUseRelease(acquire, () => use, release => Effect.sync(release));
30
- }
31
- // Stage the version, publish it under the lock, and always remove an
32
- // unpublished stage, including after Ctrl-C or SIGTERM.
19
+ // Stage the version, publish it under the lock (to completion once the lock
20
+ // is ours), and always remove an unpublished stage, including after Ctrl-C or
21
+ // SIGTERM.
33
22
  function deliverPayload(...args) {
34
23
  return Effect.acquireUseRelease(attempt(() => stageSyncPayload(...args)), staged => holdSyncLock(staged.appRoot, attempt(staged.publish)).pipe(Effect.map(warnings => ({ destination: staged.destination, wasPresent: staged.wasPresent, warnings }))), staged => Effect.sync(staged.discard));
35
24
  }
25
+ /** Stages and publishes one version under the folder lock (tests and the fixture script). */
26
+ export function syncPayloadToDisk(...args) {
27
+ return runOrThrow(deliverPayload(...args), new AbortController().signal);
28
+ }
36
29
  async function runOrThrow(program, signal) {
37
30
  const exit = await Effect.runPromiseExit(program, { signal });
38
31
  if (Exit.isSuccess(exit))
39
32
  return exit.value;
40
33
  throw Cause.squash(exit.cause);
41
34
  }
42
- // `once`: a second signal falls through to Node's default kill.
43
35
  async function runDelivery(program) {
44
- const controller = new AbortController();
45
- let interrupted;
46
- const handleInterrupt = () => { interrupted ??= 130; controller.abort(); };
47
- const handleTerminate = () => { interrupted ??= 143; controller.abort(); };
48
- process.once('SIGINT', handleInterrupt);
49
- process.once('SIGTERM', handleTerminate);
50
- try {
51
- return await runOrThrow(program(controller.signal), controller.signal);
52
- }
53
- catch (error) {
54
- if (interrupted !== undefined)
55
- return { interrupted };
56
- throw error;
57
- }
58
- finally {
59
- process.removeListener('SIGINT', handleInterrupt);
60
- process.removeListener('SIGTERM', handleTerminate);
61
- }
36
+ const { exit, interrupted } = await runWithStops(program);
37
+ if (Exit.isSuccess(exit))
38
+ return exit.value;
39
+ if (interrupted !== undefined)
40
+ return { interrupted };
41
+ throw Cause.squash(exit.cause);
62
42
  }
63
43
  export function syncInstructionSet(out, project, plan, options) {
64
44
  return runDelivery(() => Effect.gen(function* () {
@@ -84,12 +64,18 @@ export function updateInstructionSets(out, project, isApproved, noSync) {
84
64
  const plan = yield* attempt(() => makeUpdatePlan(project, lock, payloads));
85
65
  if (!isApproved)
86
66
  return { plan, result: { absent: [], warnings: [] } };
87
- // applyUpdate's own steps are not interruptible; each version it syncs is
88
- // a nested delivery that the shared signal interrupts and cleans up.
89
- const result = yield* Effect.uninterruptible(Effect.tryPromise({
90
- try: () => applyUpdate(out, project, plan, noSync, undefined, (...args) => runOrThrow(deliverPayload(...args), signal)),
91
- catch: cause => cause,
92
- }));
67
+ // --no-sync writes the Lock under the folder lock. Otherwise applyUpdate's
68
+ // own steps are not interruptible; each version it syncs is a nested
69
+ // delivery that the shared signal interrupts and cleans up.
70
+ const result = noSync
71
+ ? yield* holdSyncLock(join(out, 'orizu'), Effect.uninterruptible(Effect.tryPromise({
72
+ try: () => publishNoSyncUpdate(out, project, plan),
73
+ catch: cause => cause,
74
+ })))
75
+ : yield* Effect.uninterruptible(Effect.tryPromise({
76
+ try: () => applyUpdate(out, project, plan, () => new Date(), (...args) => runOrThrow(deliverPayload(...args), signal)),
77
+ catch: cause => cause,
78
+ }));
93
79
  return { plan, result };
94
80
  });
95
81
  // --no-sync stages nothing to clean up, so keep Node's default signal
@@ -0,0 +1,24 @@
1
+ import { type Interrupted } from './cli-stops.js';
2
+ import { type PrunePlan, type PruneResult } from './instruction-set-update/index.js';
3
+ /** What the removal step did before a stop was handled. */
4
+ export type PruneOutcome = {
5
+ kind: 'not started';
6
+ } | {
7
+ kind: 'removed';
8
+ count: number;
9
+ } | {
10
+ kind: 'rolled back';
11
+ error: unknown;
12
+ } | {
13
+ kind: 'rollback failed';
14
+ };
15
+ export type PruneStopped = Interrupted & {
16
+ outcome: PruneOutcome;
17
+ };
18
+ /**
19
+ * Removes the approved Versions under the folder lock. Waiting for the lock
20
+ * and planning again can be stopped and change nothing. The removal itself
21
+ * always settles once it starts: applied and verified, or fully rolled back.
22
+ */
23
+ export declare function pruneInstructionSets(out: string, plan: PrunePlan, keepSpecifiers: string[]): Promise<PruneResult | PruneStopped>;
24
+ //# sourceMappingURL=instruction-prune.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instruction-prune.d.ts","sourceRoot":"","sources":["../src/instruction-prune.ts"],"names":[],"mappings":"AAIA,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC/D,OAAO,EAOL,KAAK,SAAS,EACd,KAAK,WAAW,EACjB,MAAM,mCAAmC,CAAA;AAM1C,2DAA2D;AAC3D,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GACvC;IAAE,IAAI,EAAE,iBAAiB,CAAA;CAAE,CAAA;AAE/B,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG;IAAE,OAAO,EAAE,YAAY,CAAA;CAAE,CAAA;AAElE;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,GAAG,YAAY,CAAC,CAwBtI"}
@@ -0,0 +1,33 @@
1
+ import { join } from 'node:path';
2
+ import { Cause, Effect, Exit } from 'effect';
3
+ import { runWithStops } from './cli-stops.js';
4
+ import { finishPrune, rollBackPrune, selectPruneRemovals, stagePruneRemovals, startPrune, verifyPrunedTree, } from './instruction-set-update/index.js';
5
+ import { attempt, holdSyncLock } from './instruction-sync-lock.js';
6
+ /**
7
+ * Removes the approved Versions under the folder lock. Waiting for the lock
8
+ * and planning again can be stopped and change nothing. The removal itself
9
+ * always settles once it starts: applied and verified, or fully rolled back.
10
+ */
11
+ export async function pruneInstructionSets(out, plan, keepSpecifiers) {
12
+ const state = { outcome: { kind: 'not started' } };
13
+ const program = holdSyncLock(join(out, 'orizu'), Effect.gen(function* () {
14
+ const selection = yield* Effect.tryPromise({ try: () => selectPruneRemovals(out, plan, keepSpecifiers), catch: cause => cause });
15
+ yield* Effect.uninterruptible(Effect.gen(function* () {
16
+ const prune = yield* attempt(() => startPrune(out));
17
+ yield* Effect.gen(function* () {
18
+ yield* attempt(() => stagePruneRemovals(out, prune, selection));
19
+ yield* Effect.tryPromise({ try: () => verifyPrunedTree(out), catch: cause => cause });
20
+ yield* attempt(() => finishPrune(prune));
21
+ }).pipe(Effect.catch(error => attempt(() => rollBackPrune(prune)).pipe(Effect.tapError(() => Effect.sync(() => { state.outcome = { kind: 'rollback failed' }; })), Effect.andThen(Effect.sync(() => { state.outcome = { kind: 'rolled back', error }; })), Effect.andThen(Effect.fail(error)))));
22
+ state.outcome = { kind: 'removed', count: selection.removals.length };
23
+ }));
24
+ return { skipped: selection.skipped };
25
+ }));
26
+ const { exit, interrupted } = await runWithStops(() => program);
27
+ // A failed rollback always surfaces its error, stop or not.
28
+ if (interrupted !== undefined && state.outcome.kind !== 'rollback failed')
29
+ return { interrupted, outcome: state.outcome };
30
+ if (Exit.isSuccess(exit))
31
+ return exit.value;
32
+ throw Cause.squash(exit.cause);
33
+ }
@@ -51,7 +51,6 @@ export interface SyncLockClaim {
51
51
  }
52
52
  export declare function startSyncLockClaim(appRoot: string): SyncLockClaim;
53
53
  export declare function tryClaimSyncLock({ lockPath, metadata, deadline }: SyncLockClaim): (() => void) | number;
54
- export declare function withSyncLock<T>(appRoot: string, operation: () => T): T;
55
54
  export interface SyncDiskResult {
56
55
  destination: string;
57
56
  wasPresent: boolean;
@@ -73,6 +72,5 @@ export interface StagedSync {
73
72
  /** Removes the staged version if it was not published. Safe to call more than once. */
74
73
  discard: () => void;
75
74
  }
76
- export declare function syncPayloadToDisk(out: string, project: string, plan: SyncRequestPlan, payload: SyncPayload, options?: SyncDiskOptions): SyncDiskResult;
77
75
  export declare function stageSyncPayload(out: string, project: string, plan: SyncRequestPlan, payload: SyncPayload, options?: SyncDiskOptions): StagedSync;
78
76
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/instruction-set-sync/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/instruction-set-sync/index.ts"],"names":[],"mappings":"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"}
@@ -10,9 +10,6 @@ const SYNC_LOCK_STALE_MS = 60_000;
10
10
  function isNodeError(error) {
11
11
  return error instanceof Error;
12
12
  }
13
- function sleepSync(milliseconds) {
14
- Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, milliseconds);
15
- }
16
13
  export function parseSyncTarget(value) {
17
14
  const target = value ?? 'ts';
18
15
  if (target !== 'ts')
@@ -421,7 +418,7 @@ export function startSyncLockClaim(appRoot) {
421
418
  };
422
419
  }
423
420
  // One claim attempt: returns the release function, or how long to wait before
424
- // trying again. Waiting is the caller's job so it can be blocking or not.
421
+ // trying again. The caller waits without blocking (instruction-sync-lock.ts).
425
422
  export function tryClaimSyncLock({ lockPath, metadata, deadline }) {
426
423
  while (true) {
427
424
  try {
@@ -462,27 +459,6 @@ export function tryClaimSyncLock({ lockPath, metadata, deadline }) {
462
459
  }
463
460
  };
464
461
  }
465
- export function withSyncLock(appRoot, operation) {
466
- const claim = startSyncLockClaim(appRoot);
467
- let release = tryClaimSyncLock(claim);
468
- while (typeof release === 'number') {
469
- sleepSync(release);
470
- release = tryClaimSyncLock(claim);
471
- }
472
- let result;
473
- try {
474
- result = operation();
475
- }
476
- catch (error) {
477
- release();
478
- throw error;
479
- }
480
- if (result && typeof result.then === 'function') {
481
- return Promise.resolve(result).finally(release);
482
- }
483
- release();
484
- return result;
485
- }
486
462
  // Test-only process boundary hooks. Production behavior is unchanged unless a
487
463
  // test child explicitly supplies one of the bounded ORIZU_TEST_SYNC_* values.
488
464
  function processTestMilliseconds(name, minimum, maximum) {
@@ -497,21 +473,12 @@ function processTestMilliseconds(name, minimum, maximum) {
497
473
  }
498
474
  return milliseconds;
499
475
  }
476
+ // Holds the real step in place, as a slow disk would, so a test can act mid-step.
500
477
  function holdForProcessTest(name) {
501
478
  const milliseconds = processTestMilliseconds(name, 0, 10_000);
502
479
  if (milliseconds === undefined)
503
480
  return;
504
- sleepSync(milliseconds);
505
- }
506
- export function syncPayloadToDisk(out, project, plan, payload, options = {}) {
507
- const staged = stageSyncPayload(out, project, plan, payload, options);
508
- try {
509
- const warnings = withSyncLock(staged.appRoot, staged.publish);
510
- return { destination: staged.destination, wasPresent: staged.wasPresent, warnings };
511
- }
512
- finally {
513
- staged.discard();
514
- }
481
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, milliseconds);
515
482
  }
516
483
  export function stageSyncPayload(out, project, plan, payload, options = {}) {
517
484
  const target = parseSyncTarget(options.target);
@@ -1,5 +1,5 @@
1
1
  import { type InstructionSetLockV1 } from '../instruction-set-lock/index.js';
2
- import { syncPayloadToDisk, type SyncDiskResult, type SyncPayload } from '../instruction-set-sync/index.js';
2
+ import { type SyncDiskOptions, type SyncDiskResult, type SyncPayload, type SyncRequestPlan } from '../instruction-set-sync/index.js';
3
3
  export interface UpdateResolution {
4
4
  payload: SyncPayload;
5
5
  profileIdentity: string;
@@ -16,7 +16,11 @@ export interface UpdateResult {
16
16
  absent: string[];
17
17
  warnings: string[];
18
18
  }
19
- export declare function applyUpdate(out: string, project: string, plan: UpdatePlan, noSync: boolean, now?: () => Date, sync?: (...args: Parameters<typeof syncPayloadToDisk>) => SyncDiskResult | Promise<SyncDiskResult>): Promise<UpdateResult>;
19
+ /** --no-sync: records the planned Pointers in the Lock. The caller holds the folder lock. */
20
+ export declare function publishNoSyncUpdate(out: string, project: string, plan: UpdatePlan, now?: () => Date): Promise<UpdateResult>;
21
+ export type SyncStep = (out: string, project: string, plan: SyncRequestPlan, payload: SyncPayload, options: SyncDiskOptions) => Promise<SyncDiskResult>;
22
+ /** Syncs every newly referenced Version; `sync` takes the folder lock for each one. */
23
+ export declare function applyUpdate(out: string, project: string, plan: UpdatePlan, now: () => Date, sync: SyncStep): Promise<UpdateResult>;
20
24
  export interface PrunePlan {
21
25
  lock: InstructionSetLockV1;
22
26
  removals: Array<{
@@ -38,5 +42,39 @@ export declare function planPrune(out: string, keepSpecifiers: string[]): Promis
38
42
  export interface PruneResult {
39
43
  skipped: PrunePlan['removals'];
40
44
  }
41
- export declare function applyPrune(out: string, plan: PrunePlan, keepSpecifiers?: string[]): Promise<PruneResult>;
45
+ export interface PruneSelection {
46
+ lock: InstructionSetLockV1;
47
+ removals: PrunePlan['removals'];
48
+ skipped: PrunePlan['removals'];
49
+ }
50
+ /**
51
+ * Plans again under the folder lock: keeps only approved removals that are
52
+ * still unreferenced (never adds one) and skips profiles holding unmanaged
53
+ * files. Reads only.
54
+ */
55
+ export declare function selectPruneRemovals(out: string, plan: PrunePlan, keepSpecifiers: string[]): Promise<PruneSelection>;
56
+ /** A prune in progress: what it moved aside and what it must restore on failure. */
57
+ export interface StagedPrune {
58
+ lockPath: string;
59
+ importMapPath: string;
60
+ priorLock: string;
61
+ priorImportMap: string | null;
62
+ stagingRoot: string;
63
+ staged: Array<{
64
+ removal: PrunePlan['removals'][number];
65
+ stagedPath: string;
66
+ }>;
67
+ }
68
+ export declare function startPrune(out: string): StagedPrune;
69
+ /**
70
+ * Moves each removal into the staging folder, then writes the new Lock and
71
+ * generated index. Records each move as it happens so a failure part-way can
72
+ * be rolled back.
73
+ */
74
+ export declare function stagePruneRemovals(out: string, prune: StagedPrune, selection: PruneSelection): void;
75
+ /** Verifies the pruned tree; the error names the first failure. */
76
+ export declare function verifyPrunedTree(out: string): Promise<void>;
77
+ export declare function finishPrune(prune: StagedPrune): void;
78
+ /** Puts back every moved folder, the prior Lock and the prior generated index. */
79
+ export declare function rollBackPrune(prune: StagedPrune): void;
42
80
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/instruction-set-update/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAIL,KAAK,oBAAoB,EAC1B,MAAM,kCAAkC,CAAA;AAEzC,OAAO,EAA4C,iBAAiB,EAAgB,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,kCAAkC,CAAA;AAGnK,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,WAAW,CAAA;IACpB,eAAe,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,oBAAoB,CAAA;IAC1B,WAAW,EAAE,gBAAgB,EAAE,CAAA;IAC/B,KAAK,EAAE,MAAM,EAAE,CAAA;CAChB;AAMD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,oBAAoB,CAIlF;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,MAAM,CAmCpG;AAED,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,oBAAoB,EAC1B,QAAQ,EAAE,WAAW,EAAE,GACtB,UAAU,CAiDZ;AA8CD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AA2CD,wBAAsB,WAAW,CAC/B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,OAAO,EACf,GAAG,GAAE,MAAM,IAAuB,EAClC,IAAI,GAAE,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,KAAK,cAAc,GAAG,OAAO,CAAC,cAAc,CAAqB,GACpH,OAAO,CAAC,YAAY,CAAC,CA4DvB;AAMD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,oBAAoB,CAAA;IAC1B,QAAQ,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAA;CAC5F;AAED,qBAAa,wBAAyB,SAAQ,KAAK;IACjD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,CAAA;gBAEjB,OAAO,EAAE,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,QAAQ,GAAG,UAAU,CAAA;KAAE,CAAC;CAQjF;AAyBD,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,CAiEzF;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,SAAS,CAAC,UAAU,CAAC,CAAA;CAC/B;AAED,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,cAAc,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAmFlH"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/instruction-set-update/index.ts"],"names":[],"mappings":"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"}