diff --git a/packages/metadata-protocol/src/protocol-commit-items.ts b/packages/metadata-protocol/src/protocol-commit-items.ts new file mode 100644 index 00000000000..410f7ef55d6 --- /dev/null +++ b/packages/metadata-protocol/src/protocol-commit-items.ts @@ -0,0 +1,44 @@ +// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. + +/** + * [#25467 cut 32] A stored commit row's `items` column read back as its revert + * plan, from `ObjectStackProtocolImplementation`, moved out of `protocol.ts` + * whole: `parseCommitItems`, which `listCommits` and `revertCommit` call. An + * array is the plan as stored; a string is parsed as JSON; anything else, or a + * string that is not a JSON array, reads as no items. + * + * A MOVE, not a redesign. The function below is the body of the + * `ObjectStackProtocolImplementation` method of the same name as it stood, + * re-indented one level and otherwise unedited. + * + * ## How the moved body reaches the class + * + * The shape #23050 set for `rest-server.ts` (its `data-action-routes.ts` + * header carries the full reasoning), as `protocol-batch-data.ts` applies it. + * The class keeps the method — the published `dist/*.d.ts` lists its name + * and declared signature. The body reads no class member, so the method's + * body calls the plain function, with no host. Every caller keeps calling the + * class method. + * + * The plan item type is `protocol.ts`'s own, and is imported from there as a + * type. Nothing re-exports this module, so the published surface does not + * move. + */ + +import type { CommitPlanItem } from './protocol.js'; + +/** The body of `ObjectStackProtocolImplementation#parseCommitItems`. */ +export function parseCommitItems( + raw: unknown, +): CommitPlanItem[] { + if (Array.isArray(raw)) return raw as CommitPlanItem[]; + if (typeof raw === 'string') { + try { + const p = JSON.parse(raw); + return Array.isArray(p) ? p : []; + } catch { + return []; + } + } + return []; +} diff --git a/packages/metadata-protocol/src/protocol.ts b/packages/metadata-protocol/src/protocol.ts index 3349b4afde5..18b1a6d90eb 100644 --- a/packages/metadata-protocol/src/protocol.ts +++ b/packages/metadata-protocol/src/protocol.ts @@ -427,6 +427,8 @@ import { legacyOrganizationRowsOf, withoutLegacyOrganizationRows } from './proto import { foldObjectExtendersFromRegistry } from './protocol-object-extender-fold.js'; // [#25467 cut 31] The disabled-package face of the by-name item read. import { readMetaItemFace } from './protocol-meta-item-face.js'; +// [#25467 cut 32] A stored commit row's `items` column read back as its revert plan. +import { parseCommitItems } from './protocol-commit-items.js'; /** * Canonical Zod schema per metadata type lives in @@ -2748,7 +2750,7 @@ function mutationEventMember(type: string, member: string | null | undefined): { * timeline serves it on every item of a bundled type, the canonical member * spelled out ({@link ObjectStackProtocolImplementation.listCommits}). */ -type CommitPlanItem = { type: string; name: string; existedBefore: boolean; prevVersion: number | null; member?: string }; +export type CommitPlanItem = { type: string; name: string; existedBefore: boolean; prevVersion: number | null; member?: string }; /** [#22877] The identity of a plan item or a draft within one batch: two members of one name are two. */ function commitPlanKey(item: { type: string; name: string; member?: string }): string { @@ -26479,16 +26481,8 @@ export class ObjectStackProtocolImplementation implements private parseCommitItems( raw: unknown, ): CommitPlanItem[] { - if (Array.isArray(raw)) return raw as CommitPlanItem[]; - if (typeof raw === 'string') { - try { - const p = JSON.parse(raw); - return Array.isArray(p) ? p : []; - } catch { - return []; - } - } - return []; + // [#25467 cut 32] The body moved to `protocol-commit-items.ts`; it reads no member. + return parseCommitItems(raw); } /**