Skip to content

Commit aa00362

Browse files
refactor(metadata-protocol): move the automation service's flow reads out of protocol.ts into protocol-automation-flow-reads.ts (#25467 cut 27) (#26933)
<!-- claude-projects-attribution: {"github_login":"os-project-manager"} --> _Requested by **Leehom** · [project thread](https://claude.ai/code/project/chan_01TenzsRopZj4jMbvjX8uz1X?thread=cmsg_01TenzsRopZj4jMbvjX8uz1X7JKgiM29GUcitRvoGGj5BU)_ Part of #25467 Clause-②: no Metadata-protocol: none Ruling-ref: 6270097840 Cut 27 of the `protocol.ts` split (#24586 ruling A, recorded in `6270097840`). Cuts 1–26 landed as #25494, #25518, #25538, #25589, #25601, #25623, #25642, #25719, #25731, #25740, #25797, #25939, #25972, #26014, #26104, #26168, #26264, #26317, #26350, #26366, #26404, #26449, #26654, #26704, #26807 and #26873. The claim is `6452474807`. It takes the cut 27 proposal of the cut 26 report (`6451437092`), a themed group. All three members passed the AST screen and the read-seam census, and all three moved unedited. Three `ObjectStackProtocolImplementation` members move unedited into one new module, `packages/metadata-protocol/src/protocol-automation-flow-reads.ts` (#23050 shape B). They are the protocol's flow reads from the `automation` service, the engine of this process: - `resolveFlowCanonicalizer`: the service's `canonicalizeStoredFlow`, bound, for the doors that canonicalize a stored flow body. It returns nothing when the service offers none. - `resolveFlowRegistrationReader`: the service's `getFlowRegistration`, bound, for a `flow` type only (#23775). - `flowRegistrationsOf`: the list's `registrations`, that reader's verdict per listed non-draft item (#23316). `protocol.ts` loses 9 net lines (29,187 to 29,178). The cut is move-only, and the card stays open for later cuts. Branch `claude/project-thread-ybjm3h` is the harness-pinned branch for this thread. It was restarted from `main` `161e00e4ea` (after cut 26's merge). It names no issue, so the claim comment is the identity record. It holds the move commit `13cd879d32` and two merges of `main`: - `4581139c4e` (10 commits) brings in #26880, whose `protocol.ts` change (+5) auto-merged. - `e78313a068` (8 commits) brings in #26856 (+76 / −3 in `protocol.ts`) and #26851. The first merge's derivation reported a STALE TREE on two scripts, so `main` was merged again. `protocol.ts` auto-merged both times with no conflict. So the merged tree was measured against `main` itself as well (see "The merged tree against `main`"). ## Serial with the file's in-flight PRs The claim named #26856, #26861 and #26880 as also editing `protocol.ts` and asked for a `git merge-tree` against each before this PR was opened. All three had merged by then: - **#26880** and **#26856** are in this branch's two merges. Their `protocol.ts` hunks auto-merged, and none of their changed lines falls in the three moved bodies or their stubs. - **#26861** (the layered read's bundle member selector) merged into `main` after the second merge. It edits `protocol.ts` (+44 / −9 between `main` and this head) and `protocol.lookup-artifact-item-call-sites.test.ts`. It names none of the three members. `git merge-tree` of this head with `main` `8074feb642` is clean. On that merged tree: - the AST compare against `main`'s `protocol.ts` reads 371 tokens, 0 differ, with 302 class members, 299 byte-identical and 3 stubs; - `tsc --noEmit` in `packages/metadata-protocol` exits 0; - the tree differs from `main` by this cut alone, 2 files, +123 / −28. The open PRs were checked against the head `e78313a068` too. Of the 38 open, four touch this package: - **#26912** edits `protocol.ts` (+703 / −2 over 8 files) and names none of the three. Its merge-tree is clean. - **#26928** touches one test file. Its merge-tree is clean. - **#26920** and **#26831** report conflicts, but **not with this cut**. Each conflicts with `main` alone on exactly the same paths, and none of those paths is in this change: - #26920: `scripts/engine-double-contract.pinned.json` and `ui/packages/app-shell/src/views/metadata-admin/i18n.ts`; - #26831: `content/docs/protocol/kernel/i18n-standard.mdx`, `packages/lint/src/validate-translation-references.test.ts`, `packages/spec/src/system/translation.zod.ts` and `ui/packages/i18n/src/utils/spec-translations.ts`. Against the move commit alone, both are clean. `main` moved seven commits after the second merge: #26894, #26901, #26905, #26908, #26861, #26913 and #26915. Only #26861 touches this package (above). The derivation on `e78313a068` found nothing stale, so `main` was not merged a third time. The PR's merge ref runs them against this cut. ## The order's screen (private statics, `new Error(`, the read-seam census) All three members passed: - **No private-static read.** The AST walk found no access on the `ObjectStackProtocolImplementation` identifier and none on `this.constructor`. - **No error constructed.** No body has `new Error(`, so no `PRODUCERS` row is owed. - **Read-seam census.** `check-durability-degradation-log-level --list` was taken on the base and again on the cut: `88 read seam(s)` and an identical list once `[@:][0-9]+` is stripped. The full readings are under "The durability `--list`". ## What moves | Member | Base line | Visibility | Body lines | AST tokens (params + return + body) | Reads | |---|---|---|---|---|---| | `resolveFlowCanonicalizer` | `:6585` | private | 12 | 134 | `getServicesRegistry` (field) | | `resolveFlowRegistrationReader` | `:6693` | private | 7 | 95 | `getServicesRegistry` (field); module-level `canonicalMetaType` | | `flowRegistrationsOf` | `:6711` | private | 9 | 142 | `resolveFlowRegistrationReader` (method) | `protocol-automation-flow-reads.ts` has 104 lines. ## The shape (#23050 shape B, as cuts 1–26 apply it) - **The class keeps all three members.** Each keeps its name, docblock, signature and position. Each body now delegates, marked `[#25467 cut 27]`. - **`AutomationFlowReadsHost`** types the two members the bodies read as the class members themselves (`ObjectStackProtocolImplementation['getServicesRegistry']` and `['resolveFlowRegistrationReader']`). Each function's `this` is a `Pick` of the members it reads. - **`getServicesRegistry`, the constructor-supplied field, is handed over as a getter** (the hand-over of cuts 20, 24 and 26). So each read finds the registry at call time, as before. - **`flowRegistrationsOf`'s call to `resolveFlowRegistrationReader` is handed over as a closure**, `(...a) => this.resolveFlowRegistrationReader(...a)`, as the order asked. So that call still reaches the class method (now its stub), not the moved function directly. - **No member changes visibility.** - **Every caller still calls the class method:** - `resolveFlowCanonicalizer`: 4 callers (`:20784`, `:21680`, `:25284`, `:25575`, base); - `resolveFlowRegistrationReader`: `flowRegistrationsOf` and `:11244`; - `flowRegistrationsOf`: `:10100`. None changes. ## Module-level declarations, by reader: no import leaves `protocol.ts` Measured by an AST walk over each body's identifiers, against `protocol.ts`'s top-level declarations and import bindings (property names excluded): | Name | Where `protocol.ts` has it | Other readers in `protocol.ts` | What this cut does | |---|---|---|---| | `canonicalMetaType` | its own export | yes (22 references at head) | stays; the new module imports it from `./protocol.js`, read at call time only | | `FlowRegistration` (type) | `@objectstack/spec/api` | yes (the two stubs' declared signatures, and others) | stays; imported as a type too | | `StoredFlowCanonicalization` (type) | `./stored-migration.js` | yes (the stub's declared return type, and others) | stays; imported as a type too | So the top level of `protocol.ts` changes by the new module's import alone. No import comment moves. ## The published `.d.ts` The series bar is ruling `6348891160`: sorted-union identity, measured first, with raw identity reported when it holds. **Both hold for this cut**, including on the merged tree against `main`. The cut adds one import statement and its comment ahead of every class docblock, so the cut 25 comment-offset trap was watched. It did not fire: the raw hash is identical at both ends. Base `161e00e4ea` and head `13cd879d32` were built with `pnpm --filter @objectstack/metadata-protocol build` against one dependency tree. The closure was built at head by a full `pnpm build` (116/116). For the base build, the package's `src/` was swapped tree-only to base (the new module removed) and restored from `HEAD` under a trap. Afterwards `git diff HEAD` was empty, `git status` was clean, and both touched blobs equalled `HEAD`'s. - **Normalised sha256** (the ruling's bar): `c5edca148ff159d4ee49cb2a2b739a2db8695df0267142816c084fb94ca80dce` at both ends, on `dist/index.d.ts` and `dist/index.d.cts`. The normaliser sorted 80 string-literal union runs. **Sorted-union identity holds.** - **Raw sha256**: `455d53280fb9c9226324aeb678e5da84e5a0efae88a4bf210d35c4405942d1b5` at both ends, 777,661 bytes. **Raw identity holds.** - **The two builds differ where they should.** - `index.js` hashes `c9423dc904760728…` at base and `2dcd91000df2937a…` at head (`index.cjs` `599562da548797ec…` → `362063271dc2cdba…`). - `….call(host` goes 0 → 1 for each of the three members in both bundles. - Each `function …(` declaration goes 0 → 1. - **Positive control** on the head tree. `private` was dropped from `resolveFlowRegistrationReader` on disk (restored from `HEAD` under a trap) and the package rebuilt. Both `.d.ts` files move to `409763bd3a5619d6…` (normalised `2856b5a8fc02c6ba…`, which differs from the bar's `c5edca14…`) and print `resolveFlowRegistrationReader(type: string): ((name: string) => FlowRegistration) | undefined;`. So the bar can see a change on these members. - **Export tables.** The ESM and CJS bundles, loaded at runtime from the package, each export the same 78 names at base and head. The sorted list hashes to `9f18a0177ac736ed…` on all of them. None of the three functions, and not `AutomationFlowReadsHost`, appears. ### The merged tree against `main` The merges brought in #26880's and #26856's `protocol.ts` changes, so the merged tree `e78313a068` was measured against `main` `57820085fa`, its second parent, in the same way. The closure was rebuilt by a full `pnpm build` (116/116), and `main`'s package `src/` was swapped in tree-only and restored under a trap. The merged tree differs from `main` only by this cut: 2 files, +123 / −28. - **`.d.ts`**: raw `4f48a58b638106f9…` (779,140 bytes) and normalised `6b3acbaf32ddd812…`, the same at `main` and merged. Both identities hold. - **`index.js`**: `9c5d5525453d5395…` at `main`, `3f469d2dc9064d24…` merged. Export tables: 78 names, `9f18a0177ac736ed…` on both. - **AST compare**, `main`'s `protocol.ts` against the merged one: 371 tokens, 0 differ. - **Suite**: `main` and merged both give 21,719 tests (21,693 passed, 0 failed, 26 skipped, 277 files), per test identical. No changeset: `skip-changeset`, per ruling `6348891160`. ## The durability `--list` `check-durability-degradation-log-level` exits 0 at both ends with identical output: `88 read seam(s)` at both ends. Its `--list` is **identical once `[@:][0-9]+` is stripped** (164 lines, and no entry changes file). - None of the three bodies has a `try`, and none reads the gate's read vocabulary (`find`/`findOne`/`count`). - No seam enters or leaves the census. - On the merged tree the list is identical too, and the verdict still reads `88 read seam(s)`. ## Proof of move-only **Bodies, by AST token.** The compare reads the TypeScript compiler's AST leaf tokens, with JSDoc skipped, over the parameters (less the added `this`), the return type and the body. It compares base `protocol.ts` at `161e00e4ea` against the head module: ``` resolveFlowCanonicalizer: base tokens 134, head tokens 134, differ 0, text-equal(ws-collapsed, comments incl.) true resolveFlowRegistrationReader: base tokens 95, head tokens 95, differ 0, text-equal(ws-collapsed, comments incl.) true flowRegistrationsOf: base tokens 142, head tokens 142, differ 0, text-equal(ws-collapsed, comments incl.) true TOTAL tokens=371 differ=0 members=3 CLASS members base=301 head=301 order-same=true byte-identical=298 stubs-with-identical-docblock+signature=3 other=[] TOP base=259 head=260 byte-identical=259 ``` **Negative controls**, one per member. Each changed one token in an in-memory copy of the head module, and only the mutated member moved (differ 1; the other two stayed 0): ``` "typeof canonicalize !== 'function'" -> "… !== 'object'" resolveFlowCanonicalizer differ 1 "canonicalMetaType(type) !== 'flow'" -> "… !== 'view'" resolveFlowRegistrationReader differ 1 "typeof name !== 'string'" -> "… !== 'number'" flowRegistrationsOf differ 1 ``` - **Class side.** There are 301 members at base and at head, in the same order. The 298 that did not move are byte-identical to base, leading comments included. All three stubs sit at their base positions and keep their docblocks and signatures byte-identical. - **Top level of `protocol.ts`.** All 259 base statements are byte-identical, leading comments included. Head adds one statement, the new module's import. - **Size.** +123 / −28 over 2 files, 151 changed lines (the proposal's estimate was 140–190). ## Readers of the moved lines The tests and scripts that read `protocol.ts` by path, the test files in `packages/`, `docs/qa/`, `scripts/` and the `@objectstack/spec` liveness ledgers were grepped for the three member names. - **By path: none reads a moved line.** The only hits outside the two source files are comments: the header of `protocol.flow-canonicalizer.test.ts` and a docblock in `runtime-authoring-gate.ts`. The two CHANGELOGs also mention them. - **Behaviour, no edit owed.** `protocol.flow-canonicalizer.test.ts` drives `resolveFlowCanonicalizer` through the protocol's doors. It passes at both ends, in the package suite. - **The liveness ledgers.** No row points at any of the three. Carried forward: `manifest.json`'s `dependencies` row → `protocol.ts#resolveWritePackageScope` (cut 19), and `seed.json` → `protocol.ts#applySeedBodies` (cut 14). These are `packages/spec/**`, outside this card. - **ADR anchors.** `check-adr-anchors` exits 0 with identical output at both ends (1,897 decision-letter citations, 60,008 citations). No moved line cites an ADR. - **Engine-double contract** (`check-engine-double-contract`): exits 0 at both ends. - The `updateData`/`deleteData` seams keep their entries at new line numbers (13898 → 13889, 13923 → 13914). - `productionFiles` is 3,810 at base and 3,812 at head. The +2 are the new file and the gitignored `packages/spec/src/migrations/registry.ts` that the spec build writes in the head tree, as in cuts 20–26. - **Identical output at both ends:** `check-adr-anchors`, `check-adr-symbol-anchors`, `check-system-context-census`, `check-tenant-audit-census`, `check-query-options-erasure-ratchet`, `check-filter-alias-parity` and `check-durability-degradation-log-level`. `check-nul-bytes` differs only in the scanned file count, +1. The base-end readings were taken in a clean detached worktree at `161e00e4ea`. ## Verification - `tsc --noEmit` in `packages/metadata-protocol` exits 0 at head, on the merged tree, and on the merge-tree with `main` `8074feb642`. - `pnpm exec eslint --no-inline-config packages/metadata-protocol` exits 0 with no output (the whole touched package, with the root `lint` script's flags). - **`packages/metadata-protocol` suite**, compared per test name and status. Each leg ran vitest `--maxWorkers=2` with the JSON reporter under the shared verify lock. - Base `161e00e4ea`: 21,692 tests (21,666 passed, 0 failed, 26 skipped), 274 files. - Head `13cd879d32`: 21,692 tests (21,666 passed, 0 failed, 26 skipped), 274 files. - None lost, none added, none changed status. The base leg is the package `src/` swapped tree-only from `161e00e4ea` (the new module removed) and restored from `HEAD` under a trap. - The merged head `e78313a068` and `main` `57820085fa` both give 21,719 tests, per test identical (0 lost, 0 added, 0 changed). - `check-platform-checklist --changed-from origin/main` (merged tree): OK, 31 anchors judged, 0 lost. - **Governed surface.** `check-governed-merges --branch claude/project-thread-ybjm3h` finds 0 of 2 paths in the register (13 surfaces), so the PR is NOT governed. It has 151 changed lines, under the 3,000-line human-merge bar. - **Derived gates.** `dispatch-gates --commands --repo objectstack-ai/objectstack` derives 46 gates on 2 changed paths from `e78313a068`, with no stale-tree finding. All 46 exit 0 after the full `pnpm build` (116/116). `dispatch-gates --ran` reports 46 derived, 46 run, 0 NOT-MEASURED and 0 UNRUN, and exits 0. ## Carry-forward These stay in `protocol.ts`: - **The read-seam members** (cut 21): `findEnvironmentRows`, `packagelessAddress`, `findServedOverlayRow`, `foldStoredCollection`, `applyObjectRegistryMutation`, `unmanagedImportCollisions`, `rollBackUnmanagedImport`, `readRevertableCommit` and `storedFlowBindingAgrees`. `rethrowUnlessMetadataStoreUnprovisioned` cannot move at all. - Public members whose return type is inferred. - **The bodies kept by a by-path reader:** - `probeRecord`, `getMetaItemCached`, `findReferencesToMeta`, `refuseUnmintableMetaType` and `metaTypeNamespaceExists`. - `viewContainerNameCollisionRefusal` with `overlaidShippedContainerViewNames`, and `reportPageRequiresAbsentAtLoad`. - The 7 `applyRegistryWriteThrough` callers, `readCodeLayerForCarryForward` and `ensureObjectStorage`. - `emitMetadataMutation`, `isArtifactBacked` and `isNestedArtifactField` (the `lookupArtifactItem` site pins), and `getOverlayRepo`. - The private-static readers: `refusePackagedBaseRemoval`, `packagedBaseRefusal`, `runPublishSideEffects`, `promoteDraftForPublish`, `publishPackageDrafts` and `discardPackageDrafts`. - The field writers: `warnClosureReadUnavailable` and `resolveSduiManifest`. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_016SP1spj613tyGCgxoD1An6 Co-authored-by: Claude <noreply@anthropic.com>
1 parent beb09fb commit aa00362

2 files changed

Lines changed: 123 additions & 28 deletions

File tree

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license.
2+
3+
/**
4+
* [#25467 cut 27] The automation service's flow reads, from
5+
* `ObjectStackProtocolImplementation`, moved out of `protocol.ts` whole: the
6+
* three members through which this protocol asks the `automation` service —
7+
* the engine of THIS process — about flows.
8+
*
9+
* - `resolveFlowCanonicalizer` — the service's `canonicalizeStoredFlow`, bound,
10+
* for the doors that canonicalize a stored flow body; nothing when the
11+
* service offers none.
12+
* - `resolveFlowRegistrationReader` — the service's `getFlowRegistration`,
13+
* bound, for a `flow` type only (#23775).
14+
* - `flowRegistrationsOf` — the list's `registrations`: that reader's verdict
15+
* per listed, non-draft item (#23316).
16+
*
17+
* A MOVE, not a redesign. Each function below is the body of the
18+
* `ObjectStackProtocolImplementation` method of the same name as it stood,
19+
* re-indented one level and otherwise unedited.
20+
*
21+
* ## How the moved bodies reach the class
22+
*
23+
* The shape #23050 set for `rest-server.ts` (its `data-action-routes.ts`
24+
* header carries the full reasoning), as `protocol-batch-data.ts` applies it.
25+
* The class keeps each method — the published `dist/*.d.ts` lists its name,
26+
* docblock and declared signature — and its body is one literal of exactly
27+
* the {@link AutomationFlowReadsHost} members it reads, plus a `.call`. The
28+
* constructor-supplied `getServicesRegistry` field is handed over as a
29+
* getter, so each read finds the registry as it stands at call time;
30+
* `flowRegistrationsOf`'s call to `resolveFlowRegistrationReader` is handed
31+
* over as a closure, so it still reaches the class method. Every caller keeps
32+
* calling the class methods.
33+
*
34+
* What the bodies read from elsewhere, they import from where `protocol.ts`
35+
* imports it. Nothing re-exports this module, so the published surface does
36+
* not move.
37+
*/
38+
39+
import type { FlowRegistration } from '@objectstack/spec/api';
40+
import type { ObjectStackProtocolImplementation } from './protocol.js';
41+
import { canonicalMetaType } from './protocol.js';
42+
import type { StoredFlowCanonicalization } from './stored-migration.js';
43+
44+
/**
45+
* The `ObjectStackProtocolImplementation` members the functions below read —
46+
* every one of them, and no other; each function's `this` is the `Pick` of
47+
* the members it reads. Each is typed AS the class member (an indexed access
48+
* on the class), so a change to a member's signature on the class is a change
49+
* here too, and naming a member the class does not have is a compile error.
50+
*/
51+
export interface AutomationFlowReadsHost {
52+
readonly getServicesRegistry: ObjectStackProtocolImplementation['getServicesRegistry'];
53+
readonly resolveFlowRegistrationReader: ObjectStackProtocolImplementation['resolveFlowRegistrationReader'];
54+
}
55+
56+
/** The body of `ObjectStackProtocolImplementation#resolveFlowCanonicalizer`; the method's docblock there is its contract. */
57+
export function resolveFlowCanonicalizer(
58+
this: Pick<AutomationFlowReadsHost, 'getServicesRegistry'>,
59+
):
60+
((name: string, body: unknown, options?: { includeRetired?: boolean }) => StoredFlowCanonicalization) | undefined {
61+
const automation = this.getServicesRegistry?.().get('automation') as
62+
| {
63+
canonicalizeStoredFlow?: (
64+
name: string, definition: unknown, options?: { includeRetired?: boolean },
65+
) => StoredFlowCanonicalization;
66+
}
67+
| undefined;
68+
const canonicalize = automation?.canonicalizeStoredFlow;
69+
if (typeof canonicalize !== 'function') return undefined;
70+
return (name, body, options) => (options === undefined
71+
? canonicalize.call(automation, name, body)
72+
: canonicalize.call(automation, name, body, options));
73+
}
74+
75+
/** The body of `ObjectStackProtocolImplementation#resolveFlowRegistrationReader`; the method's docblock there is its contract. */
76+
export function resolveFlowRegistrationReader(
77+
this: Pick<AutomationFlowReadsHost, 'getServicesRegistry'>,
78+
type: string,
79+
): ((name: string) => FlowRegistration) | undefined {
80+
if (canonicalMetaType(type) !== 'flow') return undefined;
81+
const automation = this.getServicesRegistry?.().get('automation') as
82+
| { getFlowRegistration?: (name: string) => FlowRegistration }
83+
| undefined;
84+
const read = automation?.getFlowRegistration;
85+
if (typeof read !== 'function') return undefined;
86+
return (name) => read.call(automation, name);
87+
}
88+
89+
/** The body of `ObjectStackProtocolImplementation#flowRegistrationsOf`; the method's docblock there is its contract. */
90+
export function flowRegistrationsOf(
91+
this: Pick<AutomationFlowReadsHost, 'resolveFlowRegistrationReader'>,
92+
type: string,
93+
items: readonly unknown[],
94+
): { registrations?: Record<string, FlowRegistration> } {
95+
const read = this.resolveFlowRegistrationReader(type);
96+
if (!read) return {};
97+
const entries: Array<[string, FlowRegistration]> = [];
98+
for (const it of items) {
99+
const name = (it as { name?: unknown } | null | undefined)?.name;
100+
if (typeof name !== 'string' || (it as { _draft?: unknown })._draft === true) continue;
101+
entries.push([name, read(name)]);
102+
}
103+
return { registrations: Object.fromEntries(entries) };
104+
}

‎packages/metadata-protocol/src/protocol.ts‎

Lines changed: 19 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,8 @@ import { saveConflict } from './protocol-save-conflict.js';
417417
import { emitMetaItemPublished, notifyMutationListenersLocal, publishMetadataMutation, runMutationProjector } from './protocol-mutation-fan-out.js';
418418
// [#25467 cut 26] The runtime authoring gate's deployment-posture probes: org wall, tenancy, RLS keys, hierarchy.
419419
import { hierarchyResolverMounted, orgWallEnforced, rlsMembershipResolverKeys, tenancyPostureInForce } from './protocol-authoring-posture-probes.js';
420+
// [#25467 cut 27] The automation service's flow reads: the stored-flow canonicalizer and the engine's registrations.
421+
import { flowRegistrationsOf, resolveFlowCanonicalizer, resolveFlowRegistrationReader } from './protocol-automation-flow-reads.js';
420422

421423
/**
422424
* Canonical Zod schema per metadata type lives in
@@ -6588,18 +6590,12 @@ export class ObjectStackProtocolImplementation implements
65886590
*/
65896591
private resolveFlowCanonicalizer():
65906592
((name: string, body: unknown, options?: { includeRetired?: boolean }) => StoredFlowCanonicalization) | undefined {
6591-
const automation = this.getServicesRegistry?.().get('automation') as
6592-
| {
6593-
canonicalizeStoredFlow?: (
6594-
name: string, definition: unknown, options?: { includeRetired?: boolean },
6595-
) => StoredFlowCanonicalization;
6596-
}
6597-
| undefined;
6598-
const canonicalize = automation?.canonicalizeStoredFlow;
6599-
if (typeof canonicalize !== 'function') return undefined;
6600-
return (name, body, options) => (options === undefined
6601-
? canonicalize.call(automation, name, body)
6602-
: canonicalize.call(automation, name, body, options));
6593+
// [#25467 cut 27] The body moved to `protocol-automation-flow-reads.ts` (see `AutomationFlowReadsHost`).
6594+
const readGetServicesRegistry = () => this.getServicesRegistry;
6595+
const host: ThisParameterType<typeof resolveFlowCanonicalizer> = {
6596+
get getServicesRegistry() { return readGetServicesRegistry(); },
6597+
};
6598+
return resolveFlowCanonicalizer.call(host);
66036599
}
66046600

66056601
/**
@@ -6695,13 +6691,12 @@ export class ObjectStackProtocolImplementation implements
66956691
* cross-process store is read.
66966692
*/
66976693
private resolveFlowRegistrationReader(type: string): ((name: string) => FlowRegistration) | undefined {
6698-
if (canonicalMetaType(type) !== 'flow') return undefined;
6699-
const automation = this.getServicesRegistry?.().get('automation') as
6700-
| { getFlowRegistration?: (name: string) => FlowRegistration }
6701-
| undefined;
6702-
const read = automation?.getFlowRegistration;
6703-
if (typeof read !== 'function') return undefined;
6704-
return (name) => read.call(automation, name);
6694+
// [#25467 cut 27] The body moved to `protocol-automation-flow-reads.ts` (see `AutomationFlowReadsHost`).
6695+
const readGetServicesRegistry = () => this.getServicesRegistry;
6696+
const host: ThisParameterType<typeof resolveFlowRegistrationReader> = {
6697+
get getServicesRegistry() { return readGetServicesRegistry(); },
6698+
};
6699+
return resolveFlowRegistrationReader.call(host, type);
67056700
}
67066701

67076702
/**
@@ -6713,15 +6708,11 @@ export class ObjectStackProtocolImplementation implements
67136708
* `Object.fromEntries`, so a name is an own key whatever it spells.
67146709
*/
67156710
private flowRegistrationsOf(type: string, items: readonly unknown[]): { registrations?: Record<string, FlowRegistration> } {
6716-
const read = this.resolveFlowRegistrationReader(type);
6717-
if (!read) return {};
6718-
const entries: Array<[string, FlowRegistration]> = [];
6719-
for (const it of items) {
6720-
const name = (it as { name?: unknown } | null | undefined)?.name;
6721-
if (typeof name !== 'string' || (it as { _draft?: unknown })._draft === true) continue;
6722-
entries.push([name, read(name)]);
6723-
}
6724-
return { registrations: Object.fromEntries(entries) };
6711+
// [#25467 cut 27] The body moved to `protocol-automation-flow-reads.ts` (see `AutomationFlowReadsHost`).
6712+
const host: ThisParameterType<typeof flowRegistrationsOf> = {
6713+
resolveFlowRegistrationReader: (...a) => this.resolveFlowRegistrationReader(...a),
6714+
};
6715+
return flowRegistrationsOf.call(host, type, items);
67256716
}
67266717

67276718
/**

0 commit comments

Comments
 (0)