@mysten-incubation/devstack 0.2.0 → 0.4.0
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/README.md +1 -1
- package/dashboard-ui/assets/{grpc-a4usE3Nk.js → grpc-CpkDu4SA.js} +1 -1
- package/dashboard-ui/assets/{index-CRYJ4pru.js → index-jLPRmjst.js} +39 -33
- package/dashboard-ui/index.html +1 -1
- package/dist/api/inference-network.d.mts +5 -5
- package/dist/api/inference-network.mjs +5 -5
- package/dist/api/inference-network.mjs.map +1 -1
- package/dist/api/run-stack-internal.mjs +2 -3
- package/dist/api/run-stack-internal.mjs.map +1 -1
- package/dist/build-integrations/dapp-kit/index.d.mts +12 -0
- package/dist/build-integrations/dapp-kit/index.mjs +14 -1
- package/dist/build-integrations/dapp-kit/index.mjs.map +1 -1
- package/dist/build-integrations/playwright/config.d.mts +2 -1
- package/dist/build-integrations/playwright/config.mjs +1 -1
- package/dist/build-integrations/playwright/config.mjs.map +1 -1
- package/dist/build-integrations/playwright/errors.d.mts +1 -1
- package/dist/build-integrations/playwright/errors.mjs.map +1 -1
- package/dist/build-integrations/playwright/index.d.mts +2 -2
- package/dist/build-integrations/playwright/index.mjs +2 -2
- package/dist/build-integrations/playwright/wallet-context.d.mts +2 -1
- package/dist/build-integrations/playwright/wallet-context.mjs +141 -41
- package/dist/build-integrations/playwright/wallet-context.mjs.map +1 -1
- package/dist/build-integrations/runtime/dapp-kit-slot.mjs +1 -1
- package/dist/build-integrations/runtime/dapp-kit-slot.mjs.map +1 -1
- package/dist/build-integrations/vite/index.d.mts +82 -40
- package/dist/build-integrations/vite/index.mjs +281 -112
- package/dist/build-integrations/vite/index.mjs.map +1 -1
- package/dist/build-integrations/vitest/config.mjs +3 -4
- package/dist/build-integrations/vitest/config.mjs.map +1 -1
- package/dist/build-integrations/vitest/global-setup.mjs +8 -8
- package/dist/build-integrations/vitest/global-setup.mjs.map +1 -1
- package/dist/cli/doctor-probes.mjs +7 -2
- package/dist/cli/doctor-probes.mjs.map +1 -1
- package/dist/cli/main.mjs +5 -4
- package/dist/cli/main.mjs.map +1 -1
- package/dist/cli/wirings/apply.mjs +0 -1
- package/dist/cli/wirings/apply.mjs.map +1 -1
- package/dist/cli/wirings/codegen.mjs +37 -38
- package/dist/cli/wirings/codegen.mjs.map +1 -1
- package/dist/cli/wirings/dump-deployment.mjs +141 -0
- package/dist/cli/wirings/dump-deployment.mjs.map +1 -0
- package/dist/cli/wirings/snapshot.mjs +0 -1
- package/dist/cli/wirings/snapshot.mjs.map +1 -1
- package/dist/cli/wirings/up.mjs +7 -0
- package/dist/cli/wirings/up.mjs.map +1 -1
- package/dist/contracts/codegenable.d.mts +22 -25
- package/dist/contracts/codegenable.mjs +35 -4
- package/dist/contracts/codegenable.mjs.map +1 -1
- package/dist/contracts/config-bindings.mjs +43 -18
- package/dist/contracts/config-bindings.mjs.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/orchestrators/boot.d.mts +0 -10
- package/dist/orchestrators/boot.mjs +24 -54
- package/dist/orchestrators/boot.mjs.map +1 -1
- package/dist/orchestrators/codegen/bindings.mjs.map +1 -1
- package/dist/orchestrators/codegen/config-runtime.mjs +137 -112
- package/dist/orchestrators/codegen/config-runtime.mjs.map +1 -1
- package/dist/orchestrators/codegen/deployment-network-file.mjs +130 -0
- package/dist/orchestrators/codegen/deployment-network-file.mjs.map +1 -0
- package/dist/orchestrators/codegen/deployment-strict.mjs +77 -0
- package/dist/orchestrators/codegen/deployment-strict.mjs.map +1 -0
- package/dist/orchestrators/codegen/deployment.d.mts +63 -0
- package/dist/orchestrators/codegen/deployment.mjs +153 -0
- package/dist/orchestrators/codegen/deployment.mjs.map +1 -0
- package/dist/orchestrators/codegen/errors.mjs +7 -9
- package/dist/orchestrators/codegen/errors.mjs.map +1 -1
- package/dist/orchestrators/codegen/format.mjs +20 -1
- package/dist/orchestrators/codegen/format.mjs.map +1 -1
- package/dist/orchestrators/codegen/paths.mjs +1 -8
- package/dist/orchestrators/codegen/paths.mjs.map +1 -1
- package/dist/orchestrators/codegen/service.mjs +369 -141
- package/dist/orchestrators/codegen/service.mjs.map +1 -1
- package/dist/orchestrators/layers.mjs +0 -1
- package/dist/orchestrators/layers.mjs.map +1 -1
- package/dist/orchestrators/network-options.d.mts +37 -35
- package/dist/orchestrators/network-options.mjs +13 -10
- package/dist/orchestrators/network-options.mjs.map +1 -1
- package/dist/plugins/account/codegen.d.mts +3 -4
- package/dist/plugins/account/codegen.mjs +5 -7
- package/dist/plugins/account/codegen.mjs.map +1 -1
- package/dist/plugins/account/index.mjs +1 -3
- package/dist/plugins/account/index.mjs.map +1 -1
- package/dist/plugins/coin/codegen.mjs +5 -5
- package/dist/plugins/coin/codegen.mjs.map +1 -1
- package/dist/plugins/coin/index.mjs.map +1 -1
- package/dist/plugins/dashboard/domain.mjs +18 -1
- package/dist/plugins/dashboard/domain.mjs.map +1 -1
- package/dist/plugins/dashboard/schema/root.mjs +5 -3
- package/dist/plugins/dashboard/schema/root.mjs.map +1 -1
- package/dist/plugins/dashboard/schema/types.mjs +15 -2
- package/dist/plugins/dashboard/schema/types.mjs.map +1 -1
- package/dist/plugins/deepbook/codegen.mjs +4 -4
- package/dist/plugins/deepbook/codegen.mjs.map +1 -1
- package/dist/plugins/deepbook/index.d.mts +7 -3
- package/dist/plugins/deepbook/index.mjs +3 -3
- package/dist/plugins/deepbook/index.mjs.map +1 -1
- package/dist/plugins/internal/codegen-helpers.mjs +0 -1
- package/dist/plugins/internal/codegen-helpers.mjs.map +1 -1
- package/dist/plugins/package/codegen.d.mts +1 -12
- package/dist/plugins/package/codegen.mjs +43 -25
- package/dist/plugins/package/codegen.mjs.map +1 -1
- package/dist/plugins/package/dep-resolution.mjs +1 -1
- package/dist/plugins/package/dep-resolution.mjs.map +1 -1
- package/dist/plugins/package/index.d.mts +14 -11
- package/dist/plugins/package/index.mjs +6 -7
- package/dist/plugins/package/index.mjs.map +1 -1
- package/dist/plugins/seal/codegen.mjs +3 -3
- package/dist/plugins/seal/codegen.mjs.map +1 -1
- package/dist/plugins/seal/index.mjs.map +1 -1
- package/dist/plugins/sui/codegen.mjs +5 -4
- package/dist/plugins/sui/codegen.mjs.map +1 -1
- package/dist/plugins/sui/index.d.mts +10 -10
- package/dist/plugins/sui/index.mjs +1 -2
- package/dist/plugins/sui/index.mjs.map +1 -1
- package/dist/plugins/sui/move-summary-runner.mjs +29 -2
- package/dist/plugins/sui/move-summary-runner.mjs.map +1 -1
- package/dist/plugins/wallet/codegen.d.mts +8 -12
- package/dist/plugins/wallet/codegen.mjs +22 -15
- package/dist/plugins/wallet/codegen.mjs.map +1 -1
- package/dist/plugins/wallet/index.d.mts +4 -3
- package/dist/plugins/wallet/index.mjs +1 -1
- package/dist/plugins/wallet/index.mjs.map +1 -1
- package/dist/plugins/wallet/service.d.mts +2 -2
- package/dist/plugins/wallet/service.mjs +2 -3
- package/dist/plugins/wallet/service.mjs.map +1 -1
- package/dist/plugins/walrus/codegen.mjs +4 -4
- package/dist/plugins/walrus/codegen.mjs.map +1 -1
- package/dist/plugins/walrus/index.mjs +1 -1
- package/dist/plugins/walrus/index.mjs.map +1 -1
- package/dist/substrate/manifest.d.mts +17 -22
- package/dist/substrate/manifest.mjs +4 -6
- package/dist/substrate/manifest.mjs.map +1 -1
- package/dist/substrate/plugin-ctx.d.mts +6 -6
- package/dist/substrate/plugin-ctx.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/liveness.mjs.map +1 -1
- package/dist/substrate/runtime/index.mjs +1 -0
- package/dist/substrate/runtime/lifecycle/file-watcher.d.mts +1 -0
- package/dist/substrate/runtime/lifecycle/file-watcher.mjs +54 -0
- package/dist/substrate/runtime/lifecycle/file-watcher.mjs.map +1 -0
- package/dist/substrate/runtime/lifecycle/index.mjs +1 -0
- package/dist/substrate/runtime/lifecycle/watch-attribution.mjs +76 -6
- package/dist/substrate/runtime/lifecycle/watch-attribution.mjs.map +1 -1
- package/dist/substrate/runtime/manifest/manifest.mjs.map +1 -1
- package/dist/substrate/runtime/paths.mjs +1 -1
- package/dist/substrate/runtime/supervisor/start-supervisor.mjs +2 -6
- package/dist/substrate/runtime/supervisor/start-supervisor.mjs.map +1 -1
- package/dist/surfaces/cli/command-tree.mjs +6 -6
- package/dist/surfaces/cli/command-tree.mjs.map +1 -1
- package/dist/surfaces/cli/index.mjs +6 -4
- package/dist/surfaces/cli/index.mjs.map +1 -1
- package/dist/surfaces/tui/plain-renderer.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/cli/wirings/dump-ids.mjs +0 -86
- package/dist/cli/wirings/dump-ids.mjs.map +0 -1
- package/dist/orchestrators/codegen/id-config.d.mts +0 -1
- package/dist/orchestrators/codegen/id-config.mjs +0 -107
- package/dist/orchestrators/codegen/id-config.mjs.map +0 -1
- package/dist/orchestrators/codegen/output-location.mjs +0 -32
- package/dist/orchestrators/codegen/output-location.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codegen.mjs","names":[],"sources":["../../../src/plugins/package/codegen.ts"],"sourcesContent":["// Package plugin — Codegenable contribution, via the UNIFIED config-binding\n// declaration.\n//\n// Distilled doc §Outputs: \"Bindings input — the source path of every local\n// Package is read by the bindings emitter (KnownPackages filtered out).\"\n//\n// The contribution emitted here is the LIGHTWEIGHT one: package id + MVR\n// placeholder + (for local packages) the source path the bindings emitter\n// consumes. The HEAVY codegen — `@mysten/codegen` emitting typed function\n// shims — happens in the codegen ORCHESTRATOR (NOT this plugin). This file\n// declares the SEAM, not the binding bytes.\n//\n// ONE declaration, TWO derivations. A package declares its `config.ts`\n// contributions ONCE as a `ConfigBindingSet`; the framework's\n// `projectLiveConfig` / `projectStaticConfig` derive both behaviors:\n// - LIVE (boot): bakes the resolved package id literal — boot's\n// `assembleIdConfig` reads it into the loadable id-config.\n// - STATIC (committed-tree): emits `resolveId('<mvr>')` so the committed\n// `config.ts` carries NO on-chain id (resolved at app build/dev time).\n//\n// The package contribution is `aggregateOnly`: it projects into the combined\n// `generated/config.ts` (`config.packages.<name>` + top-level\n// `config.objects.<name>`) and emits NO standalone `package/<name>.ts`. The\n// `packageBindings` value is still exported on the emit context so the\n// orchestrator's `isPackageBindings` seam forwards it to the Move-bindings\n// emitter (bindings stay in `generated/bindings/`).\n\nimport { LOCAL_NETWORK_NAME } from '../../api/inference-network.ts';\nimport type { CodegenableDecl, StaticCodegenSource } from '../../contracts/codegenable.ts';\nimport {\n\tconfigCodegenable,\n\ttype ConfigBinding,\n\ttype ConfigBindingSet,\n} from '../../contracts/config-bindings.ts';\nimport type { PackageBindings } from '../../orchestrators/codegen/bindings.ts';\nimport type { JsonValue } from '../../orchestrators/codegen/id-config.ts';\nimport { mvrNamedForm, mvrNamedFormFrom } from './dep-resolution.ts';\nimport type { ResolvedLocalPackage, ResolvedKnownPackage } from './registry.ts';\n\n/** Per-network declared ids — pure literals the user supplies for\n * prod-targeting (`testnet`/`mainnet`). No resolution. */\nexport interface PackageNetworkEntry {\n\treadonly packageId: string;\n\treadonly objects?: Readonly<Record<string, string>>;\n}\n\nexport type PackageNetworks = Readonly<Record<string, PackageNetworkEntry>>;\n\n/** Codegenable shape — what each Package contributes to the codegen\n * orchestrator. Defined once on the orchestrator's `emitBindings` consumer\n * contract (`orchestrators/codegen/bindings.ts`); re-exported here as the\n * package plugin's public surface. */\nexport type { PackageBindings };\n\n/** The typed shape one `config.packages.<name>` entry exports. */\nexport interface PackageConfigEntry {\n\treadonly mvr: string;\n\t/** Convenience = `byNetwork[config.network]` (the active network's\n\t * id). */\n\treadonly packageId: string;\n\treadonly byNetwork: Readonly<Record<string, string>>;\n\t/** Resolved (local) + declared (prod) object ids for the active\n\t * network. Present only when at least one object is known. */\n\treadonly objects?: Readonly<Record<string, string>>;\n}\n\n/** The state the LIVE binding derivation reads — the resolved package's\n * active-network id + captured object ids. */\ninterface PackageLiveState {\n\treadonly packageId: string;\n\treadonly captured: Readonly<Record<string, string>>;\n}\n\ninterface PackageBindingInput {\n\treadonly name: string;\n\treadonly mvrPlaceholder: string;\n\t/** Pinned literal id (KNOWN package with a declared id). When set, the\n\t * active-network id is a LITERAL binding (identical in both paths). When\n\t * absent (a LOCAL package, or a KNOWN-shaped local stub), the id is a\n\t * RESOLVED binding: static emits `resolveId('<mvr>')`, live computes the\n\t * real resolved id from acquired state. */\n\treadonly pinnedId?: string | undefined;\n\t/** Resolved local object captures (keyed by user `capture` name).\n\t * Surfaced into `config.objects.<name>` + `packages.<name>.objects`\n\t * for the active (local) network. Empty on the committed-stub path —\n\t * the captured IDS are loaded config data (resolved at app build/dev\n\t * time), so the static path emits `resolveValue` from `objectKeys`. */\n\treadonly captured: Readonly<Record<string, string>>;\n\t/** The capture KEYS this package declares (the user `capture` option's\n\t * key set, known at config time). Drives the object-id bindings on BOTH\n\t * paths so the committed stub carries `resolveValue('package:<name>:\n\t * objects', '<key>')` references rather than a live-only `objects` field.\n\t * When omitted, falls back to the keys present in `captured` (live path).\n\t */\n\treadonly objectKeys?: ReadonlyArray<string> | undefined;\n\t/** Declared per-network literals (testnet/mainnet). */\n\treadonly networks?: PackageNetworks | undefined;\n}\n\n/**\n * Build the package's config-binding set, declared ONCE. The `name` keys the\n * `config.packages.<name>` entry; `mvrPlaceholder` is a literal in both paths;\n * the active-network id is a RESOLVED binding (sugar `resolveId('<mvr>')` when\n * `resolveViaRuntime`, otherwise a literal already-known id). Declared\n * per-network literals (testnet/mainnet) and captured objects are literals.\n *\n * The same set drives `projectStaticConfig` (committed tree) and\n * `projectLiveConfig` (boot id-config) — no parallel projectors.\n */\nconst packageConfigBindings = (input: PackageBindingInput): ConfigBindingSet<PackageLiveState> => {\n\tconst { name, mvrPlaceholder } = input;\n\n\tconst bindings: Array<ConfigBinding<PackageLiveState>> = [];\n\n\t// `packages.<name>.mvr` — pure literal in both paths.\n\tbindings.push({\n\t\tvariant: 'literal',\n\t\tconfigPath: ['packages', name, 'mvr'],\n\t\tvalue: mvrPlaceholder,\n\t});\n\n\t// The active-network id binding. Two cases:\n\t// - no pinned id (LOCAL, or KNOWN-shaped local stub) → RESOLVED (sugar\n\t// `resolveId('<mvr>')` static; live = the concrete resolved id from\n\t// `state.packageId`).\n\t// - pinned literal (KNOWN with a declared id) → LITERAL (the id stands\n\t// identically in both paths).\n\t// Reused for `packages.<name>.packageId`, `byNetwork.localnet`, and the\n\t// `mvrOverrides` entry so all three agree.\n\tconst pinned = input.pinnedId;\n\tconst idBinding = (configPath: ReadonlyArray<string>): ConfigBinding<PackageLiveState> =>\n\t\tpinned === undefined\n\t\t\t? {\n\t\t\t\t\tvariant: 'resolved',\n\t\t\t\t\tconfigPath,\n\t\t\t\t\tnamespace: 'package',\n\t\t\t\t\tkey: `${name}:packageId`,\n\t\t\t\t\tsugar: { kind: 'id', mvrPlaceholder },\n\t\t\t\t\tlive: (state) => state.packageId,\n\t\t\t\t}\n\t\t\t: { variant: 'literal', configPath, value: pinned };\n\n\tbindings.push(idBinding(['packages', name, 'packageId']));\n\tbindings.push(idBinding(['packages', name, 'byNetwork', LOCAL_NETWORK_NAME]));\n\n\t// Declared per-network literals (testnet/mainnet) — pure literals.\n\tfor (const [net, entry] of Object.entries(input.networks ?? {})) {\n\t\tbindings.push({\n\t\t\tvariant: 'literal',\n\t\t\tconfigPath: ['packages', name, 'byNetwork', net],\n\t\t\tvalue: entry.packageId,\n\t\t});\n\t}\n\n\t// Active-network objects — captured ids (local). The captured ids are\n\t// LOADED CONFIG DATA, so each is a RESOLVED binding on the generic\n\t// `resolveValue('package:<name>:objects', '<key>')` channel: the static\n\t// committed stub emits the resolver expr, the live path bakes the real\n\t// captured id AND feeds the id-config `values` channel. The key set comes\n\t// from `objectKeys` (config-known) so BOTH paths emit identical paths —\n\t// no live-only `objects` field. Falls back to the live capture keys when\n\t// `objectKeys` is absent (the live emit path).\n\tconst objectKeys = input.objectKeys ?? Object.keys(input.captured);\n\tif (objectKeys.length > 0) {\n\t\tconst objectsNamespace = `package:${name}:objects`;\n\t\tfor (const objectKey of objectKeys) {\n\t\t\tconst objectBinding = (\n\t\t\t\tconfigPath: ReadonlyArray<string>,\n\t\t\t): ConfigBinding<PackageLiveState> => ({\n\t\t\t\tvariant: 'resolved',\n\t\t\t\tconfigPath,\n\t\t\t\tnamespace: objectsNamespace,\n\t\t\t\tkey: objectKey,\n\t\t\t\tlive: (state) => (state.captured[objectKey] ?? null) as JsonValue,\n\t\t\t});\n\t\t\tbindings.push(objectBinding(['packages', name, 'objects', objectKey]));\n\t\t\t// Top-level `objects.<name>.<key>` mirror.\n\t\t\tbindings.push(objectBinding(['objects', name, objectKey]));\n\t\t}\n\t}\n\n\t// Active-network MVR override entry — `{ [mvr]: <active id> }`. A\n\t// resolved binding always emits (the resolver expr / live id); a pinned\n\t// literal emits only when non-empty.\n\tif (pinned === undefined || pinned.length > 0) {\n\t\tbindings.push(idBinding(['mvrOverrides', mvrPlaceholder]));\n\t}\n\n\treturn {\n\t\tbucket: 'config.ts',\n\t\tkind: 'package',\n\t\temitterName: 'package',\n\t\t// One Package contribution per published package — shared `'package'`\n\t\t// emitter name is by-design (the orchestrator skips its uniqueness\n\t\t// check for this flag).\n\t\tallowEmitterNameRepetition: true,\n\t\tbindings,\n\t};\n};\n\n/**\n * Build the package's `CodegenableDecl` from its binding set via the unified\n * `configCodegenable` derivation. Mode `'live'` bakes concrete values + feeds\n * the id-config; `'static'` emits resolver expressions. The decl ALSO exports\n * `packageBindings` (the `extraExports` hook) so the orchestrator's\n * `isPackageBindings` seam forwards it to the Move-bindings emitter (bindings\n * stay in `generated/bindings/`).\n */\nconst packageDecl = (\n\tset: ConfigBindingSet<PackageLiveState>,\n\tbindings: PackageBindings,\n\thow: 'static' | { readonly mode: 'live'; readonly state: PackageLiveState },\n): CodegenableDecl<'package'> =>\n\tconfigCodegenable<PackageLiveState, 'package'>(set, how, {\n\t\textraExports: { packageBindings: bindings },\n\t});\n\n/** Build the Codegenable contribution for a local package (LIVE path).\n * Bakes the resolved active-network id + captured objects. */\nexport const makeLocalCodegenable = (\n\tresolved: ResolvedLocalPackage,\n\toptions: {\n\t\treadonly excluded: boolean;\n\t\treadonly networks?: PackageNetworks;\n\t},\n): CodegenableDecl<'package'> => {\n\t// Coerce the resolved placeholder into the current `@local/<slug>` named\n\t// form at the emit seam rather than trusting it verbatim — a cache-served\n\t// `mvrPlaceholder` can be a STALE BARE slug. `mvrNamedFormFrom` is pure +\n\t// deterministic; computed ONCE so the binding default and `config.mvr`\n\t// stay equal. A LOCAL package has NO pinned id — the active-network id is\n\t// always a RESOLVED binding (live bakes the real id; static emits\n\t// `resolveId`).\n\tconst mvrPlaceholder = mvrNamedFormFrom(resolved.mvrPlaceholder);\n\tconst set = packageConfigBindings({\n\t\tname: resolved.name,\n\t\tmvrPlaceholder,\n\t\tcaptured: resolved.captured,\n\t\t...(options.networks !== undefined ? { networks: options.networks } : {}),\n\t});\n\tconst bindings: PackageBindings = {\n\t\tname: resolved.name,\n\t\tpackageId: resolved.packageId,\n\t\tmvrPlaceholder,\n\t\tsourcePath: resolved.sourcePath,\n\t\texcluded: options.excluded,\n\t};\n\treturn packageDecl(set, bindings, {\n\t\tmode: 'live',\n\t\tstate: { packageId: resolved.packageId, captured: resolved.captured },\n\t});\n};\n\n/** Build the Codegenable contribution for a known package — `sourcePath:\n * null`, no captured object ids. A KNOWN package's declared id is a PINNED\n * LITERAL (not loaded runtime data), so it renders identically in both the\n * live and static paths. */\nexport const makeKnownCodegenable = (\n\tresolved: ResolvedKnownPackage,\n\toptions: { readonly networks?: PackageNetworks } = {},\n): CodegenableDecl<'package'> => {\n\t// Defensive parity with the local emit seam: coerce to the current\n\t// `@local/<slug>` named form (preserving an already-named override).\n\tconst mvrPlaceholder = mvrNamedFormFrom(resolved.mvrPlaceholder);\n\tconst set = packageConfigBindings({\n\t\tname: resolved.name,\n\t\tmvrPlaceholder,\n\t\tcaptured: {},\n\t\tpinnedId: resolved.packageId,\n\t\t...(options.networks !== undefined ? { networks: options.networks } : {}),\n\t});\n\tconst bindings: PackageBindings = {\n\t\tname: resolved.name,\n\t\tpackageId: resolved.packageId,\n\t\tmvrPlaceholder,\n\t\tsourcePath: null,\n\t\texcluded: true, // implicit — KnownPackages never emit bindings.\n\t};\n\t// A pinned literal renders identically in both paths; derive as `static`\n\t// (the literal bindings ignore live state).\n\treturn packageDecl(set, bindings, 'static');\n};\n\n// ---------------------------------------------------------------------------\n// Stack-free codegen derivation (the `codegen` verb)\n//\n// The live `start` body resolves a package (publish/verify) and feeds the\n// resolved value into `makeLocalCodegenable` / `makeKnownCodegenable`. The\n// `staticCodegen` sources below reconstruct the SAME decls from CONFIG ALONE\n// — no chain, no publish — drawing the `packageId` from the projection\n// id-resolver (sentinel for `'placeholder'`, declared id for `'known'`). The\n// decl SHAPE is identical to the live path.\n// ---------------------------------------------------------------------------\n\n/** Build the static (stack-free) codegen source for a LOCAL package.\n * `sourcePath` is the resolved on-disk Move tree the bindings emitter\n * compiles (a local `sourcePath`; a git source whose tree has not been\n * materialized contributes `null`, so the bindings step skips it). */\nexport const makeLocalStaticCodegen = (config: {\n\treadonly name: string;\n\treadonly sourcePath: string | null;\n\treadonly mvrPlaceholder?: string | undefined;\n\treadonly excluded: boolean;\n\treadonly networks?: PackageNetworks | undefined;\n\t/** Capture KEYS declared by the user `capture` option (config-known).\n\t * The static stub emits `resolveValue('package:<name>:objects', '<key>')`\n\t * for each so the committed tree carries object-id references with NO\n\t * baked id and NO live-only `objects` field. */\n\treadonly objectKeys?: ReadonlyArray<string> | undefined;\n}): StaticCodegenSource => {\n\tconst mvrPlaceholder = mvrNamedForm(config.mvrPlaceholder ?? config.name);\n\treturn () => {\n\t\t// A LOCAL package has no pinned id — resolve the active id at app\n\t\t// build/dev time, never embed it in the committed tree. A git source\n\t\t// whose tree has NOT been materialized has no local path, so the\n\t\t// bindings emitter can't compile it; the `sourcePath` carries through\n\t\t// (null → bindings step skips it) but the `config.ts` entry is the same.\n\t\tconst set = packageConfigBindings({\n\t\t\tname: config.name,\n\t\t\tmvrPlaceholder,\n\t\t\tcaptured: {},\n\t\t\t...(config.objectKeys !== undefined ? { objectKeys: config.objectKeys } : {}),\n\t\t\t...(config.networks !== undefined ? { networks: config.networks } : {}),\n\t\t\t// No pinned id — the active id resolves at app build/dev time.\n\t\t});\n\t\tconst bindings: PackageBindings = {\n\t\t\tname: config.name,\n\t\t\t// No live publish → the committed stub carries no id (the resolver\n\t\t\t// fills it at app build/dev time). Carry the sentinel-free name.\n\t\t\tpackageId: '',\n\t\t\tmvrPlaceholder,\n\t\t\tsourcePath: config.sourcePath,\n\t\t\texcluded: config.sourcePath === null ? true : config.excluded,\n\t\t};\n\t\treturn [packageDecl(set, bindings, 'static')];\n\t};\n};\n\n/** Build the static (stack-free) codegen source for a KNOWN package. Known\n * packages already carry a literal `packageId` in config; the committed stub\n * emits it verbatim. */\nexport const makeKnownStaticCodegen = (config: {\n\treadonly name: string;\n\treadonly packageId: string;\n\treadonly upgradeCapId?: string | undefined;\n\treadonly mvrPlaceholder?: string | undefined;\n\treadonly networks?: PackageNetworks | undefined;\n}): StaticCodegenSource => {\n\tconst mvrPlaceholder = mvrNamedForm(config.mvrPlaceholder ?? config.name);\n\treturn () => {\n\t\tconst set = packageConfigBindings({\n\t\t\tname: config.name,\n\t\t\tmvrPlaceholder,\n\t\t\tcaptured: {},\n\t\t\tpinnedId: config.packageId,\n\t\t\t...(config.networks !== undefined ? { networks: config.networks } : {}),\n\t\t});\n\t\tconst bindings: PackageBindings = {\n\t\t\tname: config.name,\n\t\t\tpackageId: config.packageId,\n\t\t\tmvrPlaceholder,\n\t\t\tsourcePath: null,\n\t\t\texcluded: true,\n\t\t};\n\t\t// A known package's literal id renders the same in both paths — derive\n\t\t// the decl as `static` (the literal bindings ignore live state).\n\t\treturn [packageDecl(set, bindings, 'static')];\n\t};\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"codegen.mjs","names":[],"sources":["../../../src/plugins/package/codegen.ts"],"sourcesContent":["// Package plugin — Codegenable contribution, via the UNIFIED config-binding\n// declaration.\n//\n// Distilled doc §Outputs: \"Bindings input — the source path of every local\n// Package is read by the bindings emitter (KnownPackages filtered out).\"\n//\n// The contribution emitted here is the LIGHTWEIGHT one: package id + MVR\n// placeholder + (for local packages) the source path the bindings emitter\n// consumes. The HEAVY codegen — `@mysten/codegen` emitting typed function\n// shims — happens in the codegen ORCHESTRATOR (NOT this plugin). This file\n// declares the SEAM, not the binding bytes.\n//\n// ONE declaration, TWO derivations. A package declares its `config.ts`\n// contributions ONCE as a `ConfigBindingSet`; the framework's\n// `projectLiveConfig` / `projectStaticConfig` derive both behaviors:\n// - LIVE (boot): bakes the resolved package id literal — boot's\n// `assembleDeployment` reads it into the loadable deployment.\n// - STATIC (committed-tree): emits `requireId(dep, '<mvr>')` so the committed\n// `config.ts` carries NO on-chain id (resolved at app build/dev time).\n//\n// The package contribution is `aggregateOnly`: it projects into the combined\n// `generated/config.ts` (`config.packages.<name>` + top-level\n// `config.objects.<name>`) and emits NO standalone `package/<name>.ts`. The\n// `packageBindings` value is still exported on the emit context so the\n// orchestrator's `isPackageBindings` seam forwards it to the Move-bindings\n// emitter (bindings stay in `generated/bindings/`).\n\nimport type { CodegenableDecl, StaticCodegenSource } from '../../contracts/codegenable.ts';\nimport {\n\tconfigCodegenable,\n\ttype ConfigBinding,\n\ttype ConfigBindingSet,\n} from '../../contracts/config-bindings.ts';\nimport type { PackageBindings } from '../../orchestrators/codegen/bindings.ts';\nimport type { JsonValue } from '../../orchestrators/codegen/deployment.ts';\nimport { mvrNamedForm, mvrNamedFormFrom } from './dep-resolution.ts';\nimport type { ResolvedLocalPackage, ResolvedKnownPackage } from './registry.ts';\n\n/** Codegenable shape — what each Package contributes to the codegen\n * orchestrator. Defined once on the orchestrator's `emitBindings` consumer\n * contract (`orchestrators/codegen/bindings.ts`); re-exported here as the\n * package plugin's public surface. */\nexport type { PackageBindings };\n\n/** The typed shape one `config.packages.<name>` entry exports. Per-network\n * package ids now live in the injected deployment envelope (live local +\n * committed `deployments/<net>.ts`), resolved via\n * `config.forNetwork(net).packages.<name>.id` — so this entry carries only\n * the MVR placeholder + the default-network convenience id. */\nexport interface PackageConfigEntry {\n\treadonly mvr: string;\n\t/** The default (local) network's resolved id. */\n\treadonly packageId: string;\n\t/** Resolved (local) object ids for the default network. Present only\n\t * when at least one object is known. */\n\treadonly objects?: Readonly<Record<string, string>>;\n}\n\n/** The state the LIVE binding derivation reads — the resolved package's\n * active-network id + captured object ids. */\ninterface PackageLiveState {\n\treadonly packageId: string;\n\treadonly captured: Readonly<Record<string, string>>;\n}\n\ninterface PackageBindingInput {\n\treadonly name: string;\n\treadonly mvrPlaceholder: string;\n\t/** Pinned literal id (KNOWN package with a declared id). When set, the\n\t * active-network id is a LITERAL binding (identical in both paths). When\n\t * absent (a LOCAL package, or a KNOWN-shaped local stub), the id is a\n\t * RESOLVED binding: static emits `requireId(dep, '<mvr>')`, live computes the\n\t * real resolved id from acquired state. */\n\treadonly pinnedId?: string | undefined;\n\t/** Resolved local object captures (keyed by user `capture` name).\n\t * Surfaced into `config.objects.<name>` + `packages.<name>.objects`\n\t * for the active (local) network. Empty on the committed-stub path —\n\t * the captured IDS are loaded config data (resolved at app build/dev\n\t * time), so the static path emits `requireValue` from `objectKeys`. */\n\treadonly captured: Readonly<Record<string, string>>;\n\t/** The capture KEYS this package declares (the user `capture` option's\n\t * key set, known at config time). Drives the object-id bindings on BOTH\n\t * paths so the committed stub carries `requireValue(dep, 'package:<name>:\n\t * objects', '<key>')` references rather than a live-only `objects` field.\n\t * When omitted, falls back to the keys present in `captured` (live path).\n\t */\n\treadonly objectKeys?: ReadonlyArray<string> | undefined;\n\t/** OPT-IN Move datatypes to expose as MVR `types` overrides. Each entry is a\n\t * `'<module>::<Name>'` suffix relative to this package (the `@local/<slug>`\n\t * prefix is implied). Each emits one\n\t * `mvrOverrides.types['@local/<slug>::<module>::<Name>']` whose static value\n\t * resolves per-network as `` `${requireId(dep, \"<mvr>\")}::<module>::<Name>` ``.\n\t * Absent / empty ⇒ no `types` entries (the orchestrator emits `types: {}`).\n\t * Identical on the live and static paths (config-known, resolution-\n\t * independent); the live deployment slice ignores the value (keeps\n\t * `types: {}`). */\n\treadonly mvrTypes?: ReadonlyArray<string> | undefined;\n}\n\n/** Validate + normalize a declared MVR-type suffix. Entries are\n * `'<module>::<Name>'` relative to the package; we reject anything that does\n * not parse as two `::`-joined Move identifiers so a typo fails at config time\n * rather than emitting an `isValidNamedType`-rejected key into the override\n * map. The `@local/<slug>::` prefix is implied (and stripped if the developer\n * redundantly included it). */\nconst normalizeMvrTypeSuffix = (packageName: string, mvr: string, entry: string): string => {\n\t// Tolerate a redundant `@local/<slug>::` prefix the developer may have\n\t// pasted from a fully-qualified tag.\n\tconst suffix = entry.startsWith(`${mvr}::`) ? entry.slice(mvr.length + 2) : entry;\n\tif (!/^[A-Za-z_][\\w]*::[A-Za-z_][\\w]*$/.test(suffix)) {\n\t\tthrow new Error(\n\t\t\t`localPackage('${packageName}') mvrTypes entry '${entry}' must be '<module>::<Name>' ` +\n\t\t\t\t`(two Move identifiers joined by '::'); the '${mvr}' package prefix is implied.`,\n\t\t);\n\t}\n\treturn suffix;\n};\n\n/**\n * Build the package's config-binding set, declared ONCE. The `name` keys the\n * `config.packages.<name>` entry; `mvrPlaceholder` is a literal in both paths;\n * the active-network id is a RESOLVED binding (sugar `requireId(dep, '<mvr>')` when\n * `resolveViaRuntime`, otherwise a literal already-known id). Declared\n * per-network literals (testnet/mainnet) and captured objects are literals.\n *\n * The same set drives `projectStaticConfig` (committed tree) and\n * `projectLiveConfig` (boot deployment) — no parallel projectors.\n */\nconst packageConfigBindings = (input: PackageBindingInput): ConfigBindingSet<PackageLiveState> => {\n\tconst { name, mvrPlaceholder } = input;\n\n\tconst bindings: Array<ConfigBinding<PackageLiveState>> = [];\n\n\t// `packages.<name>.mvr` — pure literal in both paths.\n\tbindings.push({\n\t\tvariant: 'literal',\n\t\tconfigPath: ['packages', name, 'mvr'],\n\t\tvalue: mvrPlaceholder,\n\t});\n\n\t// The active-network id binding. Two cases:\n\t// - no pinned id (LOCAL, or KNOWN-shaped local stub) → RESOLVED (sugar\n\t// `requireId(dep, '<mvr>')` static; live = the concrete resolved id from\n\t// `state.packageId`).\n\t// - pinned literal (KNOWN with a declared id) → LITERAL (the id stands\n\t// identically in both paths).\n\t// Reused for `packages.<name>.packageId` and the `mvrOverrides` entry so\n\t// both agree.\n\tconst pinned = input.pinnedId;\n\tconst idBinding = (configPath: ReadonlyArray<string>): ConfigBinding<PackageLiveState> =>\n\t\tpinned === undefined\n\t\t\t? {\n\t\t\t\t\tvariant: 'resolved',\n\t\t\t\t\tconfigPath,\n\t\t\t\t\tnamespace: 'package',\n\t\t\t\t\tkey: `${name}:packageId`,\n\t\t\t\t\tsugar: { kind: 'id', mvrPlaceholder },\n\t\t\t\t\tlive: (state) => state.packageId,\n\t\t\t\t}\n\t\t\t: { variant: 'literal', configPath, value: pinned };\n\n\tbindings.push(idBinding(['packages', name, 'packageId']));\n\n\t// Active-network objects — captured ids (local). The captured ids are\n\t// LOADED CONFIG DATA, so each is a RESOLVED binding on the generic\n\t// `requireValue(dep, 'package:<name>:objects', '<key>')` channel: the static\n\t// committed stub emits the resolver expr, the live path bakes the real\n\t// captured id AND feeds the deployment `values` channel. The key set comes\n\t// from `objectKeys` (config-known) so BOTH paths emit identical paths —\n\t// no live-only `objects` field. Falls back to the live capture keys when\n\t// `objectKeys` is absent (the live emit path).\n\tconst objectKeys = input.objectKeys ?? Object.keys(input.captured);\n\tif (objectKeys.length > 0) {\n\t\tconst objectsNamespace = `package:${name}:objects`;\n\t\tfor (const objectKey of objectKeys) {\n\t\t\tconst objectBinding = (\n\t\t\t\tconfigPath: ReadonlyArray<string>,\n\t\t\t): ConfigBinding<PackageLiveState> => ({\n\t\t\t\tvariant: 'resolved',\n\t\t\t\tconfigPath,\n\t\t\t\tnamespace: objectsNamespace,\n\t\t\t\tkey: objectKey,\n\t\t\t\tlive: (state) => (state.captured[objectKey] ?? null) as JsonValue,\n\t\t\t});\n\t\t\tbindings.push(objectBinding(['packages', name, 'objects', objectKey]));\n\t\t\t// Top-level `objects.<name>.<key>` mirror.\n\t\t\tbindings.push(objectBinding(['objects', name, objectKey]));\n\t\t}\n\t}\n\n\t// Active-network MVR override entry — `mvrOverrides.packages.<mvr> = <active\n\t// id>` (the @mysten MVR override shape's `packages` map). The sibling `types`\n\t// map is OPT-IN — populated below ONLY from developer-declared `mvrTypes`\n\t// (the change from auto-enumerating every package type). A resolved binding\n\t// always emits (the resolver expr / live id); a pinned literal emits only\n\t// when non-empty.\n\tif (pinned === undefined || pinned.length > 0) {\n\t\tbindings.push(idBinding(['mvrOverrides', 'packages', mvrPlaceholder]));\n\t}\n\n\t// OPT-IN MVR `types` overrides — `mvrOverrides.types['<mvr>::<module>::<Name>']`\n\t// for each developer-declared `<module>::<Name>`. The static path emits the\n\t// per-network type tag `` `${requireId(dep, \"<mvr>\")}::<module>::<Name>` ``\n\t// (the `mvrType` sugar); the live path's value is ignored by the live\n\t// deployment slice (`deploymentFromBucket` keeps `types: {}`). Sugar bindings\n\t// never touch the generic `values` channel. No declared types ⇒ no entries\n\t// here (the orchestrator emits `types: {}`).\n\tfor (const entry of input.mvrTypes ?? []) {\n\t\tconst typeSuffix = normalizeMvrTypeSuffix(name, mvrPlaceholder, entry);\n\t\tconst tag = `${mvrPlaceholder}::${typeSuffix}`;\n\t\tbindings.push({\n\t\t\tvariant: 'resolved',\n\t\t\tconfigPath: ['mvrOverrides', 'types', tag],\n\t\t\tnamespace: 'package',\n\t\t\tkey: `${name}:mvrType:${tag}`,\n\t\t\tsugar: { kind: 'mvrType', mvrPlaceholder, typeSuffix },\n\t\t\t// Ignored by the live deployment slice; a value is required by the\n\t\t\t// binding shape. The resolved per-network tag is what the static\n\t\t\t// committed `config.ts` emits via the sugar.\n\t\t\tlive: () => tag,\n\t\t});\n\t}\n\n\treturn {\n\t\tbucket: 'config.ts',\n\t\tkind: 'package',\n\t\temitterName: 'package',\n\t\t// One Package contribution per published package — shared `'package'`\n\t\t// emitter name is by-design (the orchestrator skips its uniqueness\n\t\t// check for this flag).\n\t\tallowEmitterNameRepetition: true,\n\t\tbindings,\n\t};\n};\n\n/**\n * Build the package's `CodegenableDecl` from its binding set via the unified\n * `configCodegenable` derivation. Mode `'live'` bakes concrete values + feeds\n * the deployment; `'static'` emits resolver expressions. The decl ALSO exports\n * `packageBindings` (the `extraExports` hook) so the orchestrator's\n * `isPackageBindings` seam forwards it to the Move-bindings emitter (bindings\n * stay in `generated/bindings/`).\n */\nconst packageDecl = (\n\tset: ConfigBindingSet<PackageLiveState>,\n\tbindings: PackageBindings,\n\thow: 'static' | { readonly mode: 'live'; readonly state: PackageLiveState },\n): CodegenableDecl<'package'> =>\n\tconfigCodegenable<PackageLiveState, 'package'>(set, how, {\n\t\textraExports: { packageBindings: bindings },\n\t});\n\n/** Build the Codegenable contribution for a local package (LIVE path).\n * Bakes the resolved active-network id + captured objects. */\nexport const makeLocalCodegenable = (\n\tresolved: ResolvedLocalPackage,\n\toptions: {\n\t\treadonly excluded: boolean;\n\t\t/** OPT-IN MVR `types` to expose — `'<module>::<Name>'` suffixes. */\n\t\treadonly mvrTypes?: ReadonlyArray<string> | undefined;\n\t},\n): CodegenableDecl<'package'> => {\n\t// Coerce the resolved placeholder into the current `@local/<slug>` named\n\t// form at the emit seam rather than trusting it verbatim — a cache-served\n\t// `mvrPlaceholder` can be a STALE BARE slug. `mvrNamedFormFrom` is pure +\n\t// deterministic; computed ONCE so the binding default and `config.mvr`\n\t// stay equal. A LOCAL package has NO pinned id — the active-network id is\n\t// always a RESOLVED binding (live bakes the real id; static emits\n\t// `requireId`).\n\tconst mvrPlaceholder = mvrNamedFormFrom(resolved.mvrPlaceholder);\n\tconst set = packageConfigBindings({\n\t\tname: resolved.name,\n\t\tmvrPlaceholder,\n\t\tcaptured: resolved.captured,\n\t\t...(options.mvrTypes !== undefined ? { mvrTypes: options.mvrTypes } : {}),\n\t});\n\tconst bindings: PackageBindings = {\n\t\tname: resolved.name,\n\t\tpackageId: resolved.packageId,\n\t\tmvrPlaceholder,\n\t\tsourcePath: resolved.sourcePath,\n\t\texcluded: options.excluded,\n\t};\n\treturn packageDecl(set, bindings, {\n\t\tmode: 'live',\n\t\tstate: { packageId: resolved.packageId, captured: resolved.captured },\n\t});\n};\n\n/** Build the Codegenable contribution for a known package — `sourcePath:\n * null`, no captured object ids. A KNOWN package's declared id is a PINNED\n * LITERAL (not loaded runtime data), so it renders identically in both the\n * live and static paths. */\nexport const makeKnownCodegenable = (\n\tresolved: ResolvedKnownPackage,\n\toptions: { readonly mvrTypes?: ReadonlyArray<string> | undefined } = {},\n): CodegenableDecl<'package'> => {\n\t// Defensive parity with the local emit seam: coerce to the current\n\t// `@local/<slug>` named form (preserving an already-named override).\n\tconst mvrPlaceholder = mvrNamedFormFrom(resolved.mvrPlaceholder);\n\tconst set = packageConfigBindings({\n\t\tname: resolved.name,\n\t\tmvrPlaceholder,\n\t\tcaptured: {},\n\t\tpinnedId: resolved.packageId,\n\t\t...(options.mvrTypes !== undefined ? { mvrTypes: options.mvrTypes } : {}),\n\t});\n\tconst bindings: PackageBindings = {\n\t\tname: resolved.name,\n\t\tpackageId: resolved.packageId,\n\t\tmvrPlaceholder,\n\t\tsourcePath: null,\n\t\texcluded: true, // implicit — KnownPackages never emit bindings.\n\t};\n\t// A pinned literal renders identically in both paths; derive as `static`\n\t// (the literal bindings ignore live state).\n\treturn packageDecl(set, bindings, 'static');\n};\n\n// ---------------------------------------------------------------------------\n// Stack-free codegen derivation (the `codegen` verb)\n//\n// The live `start` body resolves a package (publish/verify) and feeds the\n// resolved value into `makeLocalCodegenable` / `makeKnownCodegenable`. The\n// `staticCodegen` sources below reconstruct the SAME decls from CONFIG ALONE\n// — no chain, no publish — drawing the `packageId` from the projection\n// id-resolver (sentinel for `'placeholder'`, declared id for `'known'`). The\n// decl SHAPE is identical to the live path.\n// ---------------------------------------------------------------------------\n\n/** Build the static (stack-free) codegen source for a LOCAL package.\n * `sourcePath` is the resolved on-disk Move tree the bindings emitter\n * compiles (a local `sourcePath`; a git source whose tree has not been\n * materialized contributes `null`, so the bindings step skips it). */\nexport const makeLocalStaticCodegen = (config: {\n\treadonly name: string;\n\treadonly sourcePath: string | null;\n\treadonly mvrPlaceholder?: string | undefined;\n\treadonly excluded: boolean;\n\t/** Capture KEYS declared by the user `capture` option (config-known).\n\t * The static stub emits `requireValue(dep, 'package:<name>:objects', '<key>')`\n\t * for each so the committed tree carries object-id references with NO\n\t * baked id and NO live-only `objects` field. */\n\treadonly objectKeys?: ReadonlyArray<string> | undefined;\n\t/** OPT-IN MVR `types` to expose — `'<module>::<Name>'` suffixes. */\n\treadonly mvrTypes?: ReadonlyArray<string> | undefined;\n}): StaticCodegenSource => {\n\tconst mvrPlaceholder = mvrNamedForm(config.mvrPlaceholder ?? config.name);\n\treturn () => {\n\t\t// A LOCAL package has no pinned id — resolve the active id at app\n\t\t// build/dev time, never embed it in the committed tree. A git source\n\t\t// whose tree has NOT been materialized has no local path, so the\n\t\t// bindings emitter can't compile it; the `sourcePath` carries through\n\t\t// (null → bindings step skips it) but the `config.ts` entry is the same.\n\t\tconst set = packageConfigBindings({\n\t\t\tname: config.name,\n\t\t\tmvrPlaceholder,\n\t\t\tcaptured: {},\n\t\t\t...(config.objectKeys !== undefined ? { objectKeys: config.objectKeys } : {}),\n\t\t\t...(config.mvrTypes !== undefined ? { mvrTypes: config.mvrTypes } : {}),\n\t\t\t// No pinned id — the active id resolves at app build/dev time.\n\t\t});\n\t\tconst bindings: PackageBindings = {\n\t\t\tname: config.name,\n\t\t\t// No live publish → the committed stub carries no id (the resolver\n\t\t\t// fills it at app build/dev time). Carry the sentinel-free name.\n\t\t\tpackageId: '',\n\t\t\tmvrPlaceholder,\n\t\t\tsourcePath: config.sourcePath,\n\t\t\texcluded: config.sourcePath === null ? true : config.excluded,\n\t\t};\n\t\treturn [packageDecl(set, bindings, 'static')];\n\t};\n};\n\n/** Build the static (stack-free) codegen source for a KNOWN package. Known\n * packages already carry a literal `packageId` in config; the committed stub\n * emits it verbatim. */\nexport const makeKnownStaticCodegen = (config: {\n\treadonly name: string;\n\treadonly packageId: string;\n\treadonly upgradeCapId?: string | undefined;\n\treadonly mvrPlaceholder?: string | undefined;\n\t/** OPT-IN MVR `types` to expose — `'<module>::<Name>'` suffixes. */\n\treadonly mvrTypes?: ReadonlyArray<string> | undefined;\n}): StaticCodegenSource => {\n\tconst mvrPlaceholder = mvrNamedForm(config.mvrPlaceholder ?? config.name);\n\treturn () => {\n\t\tconst set = packageConfigBindings({\n\t\t\tname: config.name,\n\t\t\tmvrPlaceholder,\n\t\t\tcaptured: {},\n\t\t\tpinnedId: config.packageId,\n\t\t\t...(config.mvrTypes !== undefined ? { mvrTypes: config.mvrTypes } : {}),\n\t\t});\n\t\tconst bindings: PackageBindings = {\n\t\t\tname: config.name,\n\t\t\tpackageId: config.packageId,\n\t\t\tmvrPlaceholder,\n\t\t\tsourcePath: null,\n\t\t\texcluded: true,\n\t\t};\n\t\t// A known package's literal id renders the same in both paths — derive\n\t\t// the decl as `static` (the literal bindings ignore live state).\n\t\treturn [packageDecl(set, bindings, 'static')];\n\t};\n};\n"],"mappings":"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"}
|
|
@@ -14,7 +14,7 @@ const mvrSlugify = (name) => name.toLowerCase().replace(/[^a-z0-9-]+/g, "-").rep
|
|
|
14
14
|
* the resulting `@local/<slug>` passes BOTH `hasMvrName` and
|
|
15
15
|
* `isValidNamedPackage`. Resolution never hits a real registry — the
|
|
16
16
|
* dapp-kit/`MvrClient` override map keys on this exact string and
|
|
17
|
-
* short-circuits to the
|
|
17
|
+
* short-circuits to the active network's resolved package id.
|
|
18
18
|
*/
|
|
19
19
|
const MVR_LOCAL_ORG = "@local";
|
|
20
20
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dep-resolution.mjs","names":[],"sources":["../../../src/plugins/package/dep-resolution.ts"],"sourcesContent":["// Move-dep helpers.\n//\n// `mvrSlugify` normalises a package name into the slug shape that\n// codegen emitters write into Move source as MVR placeholders.\n// Distilled doc Invariant 13: the result MUST satisfy `[a-z0-9-]+`\n// (downstream validators reject underscores).\n\n/**\n * Slugify a package name into the bare slug shape (`[a-z0-9-]+`).\n *\n * This bare slug is what codegen writes into Move-source file stems /\n * the dead `package/<slug>.ts` output path, and is the `{app}`\n * component of the MVR named form (`mvrNamedForm` below).\n */\nexport const mvrSlugify = (name: string): string =>\n\tname\n\t\t.toLowerCase()\n\t\t.replace(/[^a-z0-9-]+/g, '-')\n\t\t.replace(/^-+|-+$/g, '')\n\t\t.replace(/-{2,}/g, '-');\n\n/**\n * Local-org used for the MVR named form devstack emits as the binding\n * package default + `config.packages.<name>.mvr`. It is syntactically\n * valid per `@mysten/sui`'s `isValidSuiNSName` (it contains `@`), so\n * the resulting `@local/<slug>` passes BOTH `hasMvrName` and\n * `isValidNamedPackage`. Resolution never hits a real registry — the\n * dapp-kit/`MvrClient` override map keys on this exact string and\n * short-circuits to the
|
|
1
|
+
{"version":3,"file":"dep-resolution.mjs","names":[],"sources":["../../../src/plugins/package/dep-resolution.ts"],"sourcesContent":["// Move-dep helpers.\n//\n// `mvrSlugify` normalises a package name into the slug shape that\n// codegen emitters write into Move source as MVR placeholders.\n// Distilled doc Invariant 13: the result MUST satisfy `[a-z0-9-]+`\n// (downstream validators reject underscores).\n\n/**\n * Slugify a package name into the bare slug shape (`[a-z0-9-]+`).\n *\n * This bare slug is what codegen writes into Move-source file stems /\n * the dead `package/<slug>.ts` output path, and is the `{app}`\n * component of the MVR named form (`mvrNamedForm` below).\n */\nexport const mvrSlugify = (name: string): string =>\n\tname\n\t\t.toLowerCase()\n\t\t.replace(/[^a-z0-9-]+/g, '-')\n\t\t.replace(/^-+|-+$/g, '')\n\t\t.replace(/-{2,}/g, '-');\n\n/**\n * Local-org used for the MVR named form devstack emits as the binding\n * package default + `config.packages.<name>.mvr`. It is syntactically\n * valid per `@mysten/sui`'s `isValidSuiNSName` (it contains `@`), so\n * the resulting `@local/<slug>` passes BOTH `hasMvrName` and\n * `isValidNamedPackage`. Resolution never hits a real registry — the\n * dapp-kit/`MvrClient` override map keys on this exact string and\n * short-circuits to the active network's resolved package id.\n */\nconst MVR_LOCAL_ORG = '@local';\n\n/**\n * Build the MVR NAMED form (`@local/<slug>`) from a package name.\n *\n * This is the value emitted as BOTH the generated-binding package\n * default (`options.package ?? '@local/<slug>'`) AND\n * `config.packages.<name>.mvr` — the two MUST match so a dapp can key\n * an `MvrClient` override on `config.mvr` and have generated functions\n * resolve by name alone. Verified to satisfy `isValidNamedPackage` and\n * `hasMvrName` (see `test/plugins/package/mvr-named-form.test.ts`).\n */\nexport const mvrNamedForm = (name: string): string => `${MVR_LOCAL_ORG}/${mvrSlugify(name)}`;\n\n/**\n * Coerce a (possibly STALE) persisted MVR placeholder into the current\n * `@local/<slug>` named form.\n *\n * The package-publish cache (`projection.v4.json`'s `mvrPlaceholder`)\n * persists whatever placeholder shape was current at publish time. A\n * stack created BEFORE the `mvrSlugify`→`mvrNamedForm` change carries a\n * BARE slug (e.g. `'vault'`), which an INCREMENTAL re-apply would\n * otherwise emit verbatim — and a bare slug fails `hasMvrName`, so the\n * generated binding's `package:` default never resolves through the\n * `MvrClient` override map. We MUST always emit the named form.\n *\n * `mvrNamedForm` is not idempotent over an already-named string\n * (`mvrSlugify('@local/vault')` → `'local-vault'`), so we cannot blindly\n * re-wrap. Instead:\n * - if the placeholder is ALREADY in `@<org>/...` named form, keep it\n * verbatim (this preserves a user-supplied `mvrPlaceholder` override);\n * - otherwise treat it as a bare slug/name and wrap it via\n * `mvrNamedForm`.\n *\n * Pure + deterministic over its input, so recomputing at the emit seam is\n * always safe and always current regardless of cached projection state.\n */\nexport const mvrNamedFormFrom = (placeholder: string): string =>\n\tplaceholder.startsWith(`${MVR_LOCAL_ORG}/`) ? placeholder : mvrNamedForm(placeholder);\n"],"mappings":";;;;;;;;AAcA,MAAa,cAAc,SAC1B,KACE,YAAY,CAAC,CACb,QAAQ,gBAAgB,GAAG,CAAC,CAC5B,QAAQ,YAAY,EAAE,CAAC,CACvB,QAAQ,UAAU,GAAG;;;;;;;;;;AAWxB,MAAM,gBAAgB;;;;;;;;;;;AAYtB,MAAa,gBAAgB,SAAyB,GAAG,cAAc,GAAG,WAAW,IAAI;;;;;;;;;;;;;;;;;;;;;;;;AAyBzF,MAAa,oBAAoB,gBAChC,YAAY,WAAW,GAAG,cAAc,EAAE,IAAI,cAAc,aAAa,WAAW"}
|
|
@@ -6,7 +6,6 @@ import { SuiClient } from "../sui/mode/shared.mjs";
|
|
|
6
6
|
import { AccountValue } from "../account/service.mjs";
|
|
7
7
|
import { AccountResourceId } from "../account/index.mjs";
|
|
8
8
|
import { LocalPackagePublishOutput, PackagePublishObjectChange } from "./publish-output.mjs";
|
|
9
|
-
import { PackageNetworkEntry, PackageNetworks } from "./codegen.mjs";
|
|
10
9
|
import { PublishError } from "./errors.mjs";
|
|
11
10
|
import { GitSource } from "./git-source.mjs";
|
|
12
11
|
import { Effect } from "effect";
|
|
@@ -53,16 +52,20 @@ interface LocalPackageOptions<Publisher extends PublisherAccountMember = Publish
|
|
|
53
52
|
readonly git?: GitSource;
|
|
54
53
|
readonly mvrPlaceholder?: string;
|
|
55
54
|
readonly excludeFromCodegen?: boolean;
|
|
55
|
+
/** Move datatypes (struct / enum) to expose as MVR `types` overrides.
|
|
56
|
+
* OPT-IN: each entry is a `'<module>::<Name>'` relative to THIS package
|
|
57
|
+
* (the `@local/<slug>` prefix is implied), e.g. `['game::Lobby',
|
|
58
|
+
* 'game::Game']`. Each declared type emits one
|
|
59
|
+
* `mvrOverrides.types['@local/<slug>::<module>::<Name>']` entry whose value
|
|
60
|
+
* resolves per-network to `` `${requireId(dep, "@local/<slug>")}::<module>::<Name>` ``
|
|
61
|
+
* (the resolved package id, never baked). Absent / empty ⇒ `types: {}` — we
|
|
62
|
+
* do NOT auto-enumerate every package type (that balloons the config + every
|
|
63
|
+
* committed `deployments/<net>.ts`). */
|
|
64
|
+
readonly mvrTypes?: readonly string[];
|
|
56
65
|
/** Capture created objects from the publish output. The record
|
|
57
66
|
* form maps output keys to object-type suffixes, e.g.
|
|
58
67
|
* `{ boardId: '::board::Board' }`. */
|
|
59
68
|
readonly capture?: Capture;
|
|
60
|
-
/** Per-network declared package ids (+ optional object ids) for
|
|
61
|
-
* prod-targeting. Pure literals, no resolution: codegen merges the
|
|
62
|
-
* resolved-local id into `config.packages.<name>.byNetwork.localnet`
|
|
63
|
-
* and these literals into `byNetwork.testnet` / `byNetwork.mainnet`.
|
|
64
|
-
* A consumer flips `config.network` (env) to select active ids. */
|
|
65
|
-
readonly networks?: PackageNetworks;
|
|
66
69
|
/** Publisher account — the signer for the publish tx. Pass the
|
|
67
70
|
* result of `account('alice')` (the same plugin/resource ref used
|
|
68
71
|
* in the rest of the stack — NOT a duplicate factory call).
|
|
@@ -78,10 +81,10 @@ interface KnownPackageOptions {
|
|
|
78
81
|
readonly packageId: string;
|
|
79
82
|
readonly upgradeCapId?: string;
|
|
80
83
|
readonly mvrPlaceholder?: string;
|
|
81
|
-
/**
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
readonly
|
|
84
|
+
/** Move datatypes (struct / enum) to expose as MVR `types` overrides —
|
|
85
|
+
* see {@link LocalPackageOptions.mvrTypes}. Each entry is a
|
|
86
|
+
* `'<module>::<Name>'` relative to this package; OPT-IN, defaults to none. */
|
|
87
|
+
readonly mvrTypes?: readonly string[];
|
|
85
88
|
}
|
|
86
89
|
/** Build + publish a local Move package. The resolved value is
|
|
87
90
|
* `LocalPackageResolved` so consumers that need bindings / source
|
|
@@ -80,9 +80,9 @@ const buildLocalPlugin = (name, opts) => {
|
|
|
80
80
|
sourceHash,
|
|
81
81
|
publisher: opts.publisher.id,
|
|
82
82
|
mvrPlaceholder: opts.mvrPlaceholder ?? null,
|
|
83
|
+
mvrTypes: opts.mvrTypes ?? null,
|
|
83
84
|
excludeFromCodegen: opts.excludeFromCodegen === true,
|
|
84
85
|
capture: opts.capture ?? null,
|
|
85
|
-
networks: opts.networks ?? null,
|
|
86
86
|
git: opts.git ?? null
|
|
87
87
|
})))), Effect.orDie)),
|
|
88
88
|
watch: {
|
|
@@ -98,7 +98,7 @@ const buildLocalPlugin = (name, opts) => {
|
|
|
98
98
|
sourcePath: opts.sourcePath ?? null,
|
|
99
99
|
mvrPlaceholder: opts.mvrPlaceholder,
|
|
100
100
|
excluded: opts.excludeFromCodegen ?? false,
|
|
101
|
-
|
|
101
|
+
...opts.mvrTypes !== void 0 ? { mvrTypes: opts.mvrTypes } : {},
|
|
102
102
|
...opts.capture !== void 0 ? { objectKeys: Object.keys(opts.capture) } : {}
|
|
103
103
|
}),
|
|
104
104
|
start: ({ sui, publisher: publisherAccount }) => Effect.gen(function* () {
|
|
@@ -150,15 +150,14 @@ const buildKnownPlugin = (name, opts) => {
|
|
|
150
150
|
name,
|
|
151
151
|
packageId: opts.packageId,
|
|
152
152
|
upgradeCapId: opts.upgradeCapId ?? null,
|
|
153
|
-
mvrPlaceholder: opts.mvrPlaceholder ?? null
|
|
154
|
-
networks: opts.networks ?? null
|
|
153
|
+
mvrPlaceholder: opts.mvrPlaceholder ?? null
|
|
155
154
|
}),
|
|
156
155
|
staticCodegen: makeKnownStaticCodegen({
|
|
157
156
|
name,
|
|
158
157
|
packageId: opts.packageId,
|
|
159
158
|
mvrPlaceholder: opts.mvrPlaceholder,
|
|
160
159
|
...opts.upgradeCapId !== void 0 ? { upgradeCapId: opts.upgradeCapId } : {},
|
|
161
|
-
|
|
160
|
+
...opts.mvrTypes !== void 0 ? { mvrTypes: opts.mvrTypes } : {}
|
|
162
161
|
}),
|
|
163
162
|
start: ({ sui }) => Effect.gen(function* () {
|
|
164
163
|
const ctx = yield* PluginContext;
|
|
@@ -186,7 +185,7 @@ const makeLocalCapabilities = (name, opts, resolved) => {
|
|
|
186
185
|
captured: resolved.captured
|
|
187
186
|
}, {
|
|
188
187
|
excluded: opts.excludeFromCodegen ?? false,
|
|
189
|
-
...opts.
|
|
188
|
+
...opts.mvrTypes !== void 0 ? { mvrTypes: opts.mvrTypes } : {}
|
|
190
189
|
});
|
|
191
190
|
const projection = {
|
|
192
191
|
kind: "local",
|
|
@@ -216,7 +215,7 @@ const makeKnownCapabilities = (name, opts, resolved) => {
|
|
|
216
215
|
packageId: resolved.packageId,
|
|
217
216
|
upgradeCapId: resolved.upgradeCapId ?? opts.upgradeCapId,
|
|
218
217
|
mvrPlaceholder: resolved.mvrPlaceholder
|
|
219
|
-
}, opts.
|
|
218
|
+
}, opts.mvrTypes !== void 0 ? { mvrTypes: opts.mvrTypes } : {});
|
|
220
219
|
const projection = {
|
|
221
220
|
kind: "known",
|
|
222
221
|
name,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/plugins/package/index.ts"],"sourcesContent":["// Package plugin — barrel + factories.\n//\n// Architecture: Package is the canonical implementation of the\n// `ArtifactPublisher` substrate primitive. Many service\n// plugins depend on its publish output (Coin types, Walrus/Seal/\n// Deepbook contracts, Action outputs).\n//\n// Public surface:\n//\n// - `localPackage(name, opts)` — build + publish a Move source tree.\n// - `knownPackage(name, opts)` — verify-only against a fixed id.\n//\n// Type split (distilled doc Invariant 9): `localPackage` resolves to\n// `LocalPackage`; `knownPackage` resolves to `KnownPackage`. The\n// bindings emitter (in the codegen orchestrator) types-out KnownPackage\n// at compose time, so misuse fails at compile time rather than at\n// emit time.\n//\n// Resource id: `'package:<name>'` — one tag per user-declared package\n// (the symbolic name is part of the identity so two `localPackage`\n// calls in the same stack don't collide on the substrate's tag\n// registry). Substrate-side plugin key is the same string.\n\nimport { Effect } from 'effect';\n\nimport { projection } from '../../api/define-capabilities.ts';\nimport {\n\tcomputedInputIdentity,\n\tdefinePlugin,\n\tresource,\n\tstaticInputIdentity,\n\ttype ResourceRef,\n} from '../../api/define-plugin.ts';\nimport type { Contribution } from '../../substrate/plugin-ctx.ts';\nimport type { CodegenableDecl } from '../../contracts/codegenable.ts';\nimport type { ProjectionDecl } from '../../contracts/projection.ts';\nimport { pickCreatedByType, type LocalPackagePublishOutput } from './publish-output.ts';\nimport type { SnapshotableDecl } from '../../contracts/snapshotable.ts';\nimport type { StrategyContributorDecl } from '../../contracts/strategy-contributor.ts';\nimport { emitContributions, PluginContext } from '../../substrate/plugin-ctx.ts';\nimport { ContainerRuntimeService } from '../../runtime/docker/service.ts';\nimport {\n\tCoinRegistryService,\n\tdiscoverCoinsFromPublish,\n\ttype CoinRecord,\n\ttype CoinRegistry,\n} from '../coin/index.ts';\nimport { CacheService } from '../../substrate/runtime/cache/index.ts';\nimport { chainProbeFor } from '../../substrate/runtime/strategy-registry/index.ts';\nimport { suiResource, type SuiProbeKey } from '../sui/index.ts';\nimport type { AccountResourceId, AccountValue } from '../account/index.ts';\nimport {\n\tmakeKnownCodegenable,\n\tmakeKnownStaticCodegen,\n\tmakeLocalCodegenable,\n\tmakeLocalStaticCodegen,\n\ttype PackageNetworks,\n} from './codegen.ts';\nimport { hashMoveSources } from './build.ts';\nimport type { PublishError } from './errors.ts';\nimport { materializeGitSource, type GitSource } from './git-source.ts';\nimport { makePublishExecutor } from './publish-executor.ts';\nimport { bootPackageService, type PackageMode } from './service.ts';\nimport {\n\tPACKAGE_REGISTRY_CAPABILITY_KEY,\n\tPackageRegistryService,\n\ttype ResolvedKnownPackage,\n\ttype ResolvedLocalPackage,\n} from './registry.ts';\nimport { makeSnapshotable } from './snapshot.ts';\n\n// ---------------------------------------------------------------------------\n// Publisher account ref — explicit upstream\n// ---------------------------------------------------------------------------\n\n/** A user-supplied publisher account ref. The user passes the result\n * of `account('alice')` — NOT a bare string. Generic over the\n * literal account name so the package dependency preserves the\n * per-account resource id. */\nexport type PublisherAccountMember<Name extends string = string> = ResourceRef<\n\tAccountResourceId<Name>,\n\tAccountValue\n>;\n\n// ---------------------------------------------------------------------------\n// Resource — one per declared package, keyed by symbolic name\n// ---------------------------------------------------------------------------\n\n/** Resource id constructor. The symbolic package name is part of the tag\n * identity so the substrate's compose-time dedup detects collisions\n * cleanly (two `localPackage('foo', ...)` calls in one stack → typed\n * error at compose time). */\nexport const packageResourceId = <Name extends string>(name: Name): `package:${Name}` =>\n\t`package:${name}`;\n\n/** The literal-template resource id for a package by symbolic name. */\nexport type PackageResourceId<Name extends string> = `package:${Name}`;\n\n/** Public resolved value shapes — re-exported from `registry.ts` to\n * give consumers one stable import path. */\nexport type { ResolvedLocalPackage, ResolvedKnownPackage, ResolvedPackage } from './registry.ts';\nexport type {\n\tPickCreatedByTypeOptions,\n\tLocalPackagePublishOutput,\n\tPackagePublishObjectChange,\n} from './publish-output.ts';\nexport { pickCreatedByType } from './publish-output.ts';\nexport type { PublishError } from './errors.ts';\nexport type { PackageBindings, PackageNetworks, PackageNetworkEntry } from './codegen.ts';\nexport type { PublishExecutor } from './mode-local.ts';\n\n/** Resolved value carried by the package resource. Local packages also\n * expose the publish output so manifest emitters and capture-spec\n * callers can read it. Sibling plugin folds consume the package-owned\n * extension contribution instead of importing package internals. */\nexport type PackageCaptureMap = Readonly<Record<string, string>>;\n\ntype PackageCaptureCallback = (\n\toutput: LocalPackagePublishOutput,\n) => Readonly<Record<string, string>>;\n\nexport type PackageCapture = PackageCaptureMap;\n\nexport type CapturedPackageValues<Capture> = Capture extends PackageCaptureCallback\n\t? Readonly<Record<string, string>>\n\t: Capture extends PackageCaptureMap\n\t\t? { readonly [K in keyof Capture]: string }\n\t\t: Readonly<Record<string, string>>;\n\nexport interface LocalPackageResolved<Capture = undefined> extends Omit<\n\tResolvedLocalPackage,\n\t'captured'\n> {\n\t/** Captured object ids keyed by the user's `capture` option. */\n\treadonly captured: CapturedPackageValues<Capture>;\n\t/** Publisher account that signed this package. Kept on the live\n\t * resource value so downstream local coin plugins can mint from\n\t * publisher-owned TreasuryCaps through the centralized funding\n\t * strategy path. It is intentionally not written to generated\n\t * bindings or the package registry. */\n\treadonly publisher: AccountValue;\n\t/** Publish output — present after a fresh publish, null on\n\t * cache hit (verify-only path). Consumers that need the\n\t * output MUST tolerate null and fall back to chain reads via\n\t * the ChainProbe. */\n\treadonly publishResult: LocalPackagePublishOutput | null;\n}\n\nexport type KnownPackageResolved = ResolvedKnownPackage;\n\nexport type PackageResolved = LocalPackageResolved | KnownPackageResolved;\n\n// ---------------------------------------------------------------------------\n// Factory options\n// ---------------------------------------------------------------------------\n\nexport interface LocalPackageOptions<\n\tPublisher extends PublisherAccountMember = PublisherAccountMember,\n\tCapture extends PackageCapture | undefined = undefined,\n> {\n\t/** Local on-disk path to the Move package. Provide EXACTLY ONE of\n\t * `sourcePath` or `git`. */\n\treadonly sourcePath?: string;\n\t/** Remote git source — clone a repo and build a sub-path of it instead of\n\t * vendoring the Move tree. Cloned once into a host cache keyed by\n\t * `url + rev` (see `git-source.ts`); pin `rev` to a commit SHA or tag for\n\t * reproducibility. Mutually exclusive with `sourcePath`. */\n\treadonly git?: GitSource;\n\treadonly mvrPlaceholder?: string;\n\treadonly excludeFromCodegen?: boolean;\n\t/** Capture created objects from the publish output. The record\n\t * form maps output keys to object-type suffixes, e.g.\n\t * `{ boardId: '::board::Board' }`. */\n\treadonly capture?: Capture;\n\t/** Per-network declared package ids (+ optional object ids) for\n\t * prod-targeting. Pure literals, no resolution: codegen merges the\n\t * resolved-local id into `config.packages.<name>.byNetwork.localnet`\n\t * and these literals into `byNetwork.testnet` / `byNetwork.mainnet`.\n\t * A consumer flips `config.network` (env) to select active ids. */\n\treadonly networks?: PackageNetworks;\n\t/** Publisher account — the signer for the publish tx. Pass the\n\t * result of `account('alice')` (the same plugin/resource ref used\n\t * in the rest of the stack — NOT a duplicate factory call).\n\t *\n\t * Required for local packages: a publish tx must be signed by\n\t * SOMEONE; we make the choice explicit so two packages in the\n\t * same stack can publish under different accounts (no implicit\n\t * \"first account\" convention to memorise). Distilled doc Invariant\n\t * 4 — \"Signer MUST be an explicit upstream\". */\n\treadonly publisher: Publisher;\n}\n\nexport interface KnownPackageOptions {\n\treadonly packageId: string;\n\treadonly upgradeCapId?: string;\n\treadonly mvrPlaceholder?: string;\n\t/** Per-network declared package ids (+ optional object ids) for\n\t * prod-targeting — same as `LocalPackageOptions.networks`. Pure\n\t * literals; codegen fills `config.packages.<name>.byNetwork`. */\n\treadonly networks?: PackageNetworks;\n}\n\ninterface PackageRegistryProjectionContribution {\n\treadonly kind: 'local' | 'known';\n\treadonly name: string;\n\treadonly packageId: string;\n\treadonly upgradeCapId: string | null;\n\treadonly mvrPlaceholder: string;\n\treadonly sourcePath: string | null;\n}\n\nconst makePackageProjectionContribution = (\n\tcontribution: PackageRegistryProjectionContribution,\n): ProjectionDecl => {\n\tconst updatedAt = Date.now();\n\tconst key = `package/${contribution.name}` as `package/${string}`;\n\treturn projection({\n\t\tkind: 'package',\n\t\tkey,\n\t\tpayload: {\n\t\t\tkey,\n\t\t\trowKey: null,\n\t\t\tname: contribution.name,\n\t\t\tkind: contribution.kind,\n\t\t\tpackageId: contribution.packageId,\n\t\t\tupgradeCapId: contribution.upgradeCapId,\n\t\t\tmvrPlaceholder: contribution.mvrPlaceholder,\n\t\t\tsourcePath: contribution.sourcePath,\n\t\t\tupdatedAt,\n\t\t},\n\t\tat: updatedAt,\n\t});\n};\n\n// ---------------------------------------------------------------------------\n// Internal builders\n// ---------------------------------------------------------------------------\n\nconst normalizeCapture = <Capture extends PackageCapture | undefined>(\n\tpackageName: string,\n\tcapture: Capture,\n): PackageCaptureCallback | undefined => {\n\tif (capture === undefined) return undefined;\n\treturn (output) => {\n\t\tconst captured: Record<string, string> = {};\n\t\tfor (const [key, suffix] of Object.entries(capture)) {\n\t\t\tconst objectId = pickCreatedByType(output.objectChanges, { suffix });\n\t\t\tif (objectId === undefined) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`localPackage('${packageName}') capture '${key}' matched no created object with suffix '${suffix}'.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tcaptured[key] = objectId;\n\t\t}\n\t\treturn captured;\n\t};\n};\n\nconst buildLocalPlugin = <\n\tName extends string,\n\tconst Publisher extends PublisherAccountMember,\n\tCapture extends PackageCapture | undefined,\n>(\n\tname: Name,\n\topts: LocalPackageOptions<Publisher, Capture>,\n) => {\n\tconst packageRef = resource<PackageResourceId<Name>, LocalPackageResolved<Capture>>(\n\t\tpackageResourceId(name),\n\t);\n\tconst capture = normalizeCapture(name, opts.capture);\n\n\t// Exactly one source is required. Validated at config-evaluation time (like\n\t// `normalizeCapture`) so a typo surfaces immediately, not mid-boot.\n\tif (opts.sourcePath === undefined && opts.git === undefined) {\n\t\tthrow new Error(`localPackage('${name}'): provide either 'sourcePath' or 'git'.`);\n\t}\n\tif (opts.sourcePath !== undefined && opts.git !== undefined) {\n\t\tthrow new Error(`localPackage('${name}'): 'sourcePath' and 'git' are mutually exclusive.`);\n\t}\n\n\t// Resolve the on-disk path to build from: a local `sourcePath` is used\n\t// verbatim; a `git` source is cloned into the host cache (idempotent —\n\t// see `materializeGitSource`) and the cached path returned. Called from\n\t// both `inputIdentity` and `start`; the second call is a cache hit.\n\tconst resolveSourcePath = (): Effect.Effect<string, PublishError> =>\n\t\topts.git !== undefined\n\t\t\t? materializeGitSource(opts.git, name)\n\t\t\t: Effect.succeed(opts.sourcePath as string);\n\n\treturn definePlugin({\n\t\tid: packageRef.id,\n\t\tdependsOn: { sui: suiResource, publisher: opts.publisher },\n\t\trole: 'task',\n\t\tsection: 'package',\n\t\tinputIdentity: computedInputIdentity(() =>\n\t\t\tresolveSourcePath().pipe(\n\t\t\t\tEffect.flatMap((sourcePath) =>\n\t\t\t\t\thashMoveSources(sourcePath).pipe(\n\t\t\t\t\t\tEffect.map((sourceHash) => ({\n\t\t\t\t\t\t\tplugin: 'package',\n\t\t\t\t\t\t\tkind: 'local',\n\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\t// The MATERIALIZED path: for a git source this is the\n\t\t\t\t\t\t\t// cache dir, so the hash + identity reflect what is built.\n\t\t\t\t\t\t\tsourcePath,\n\t\t\t\t\t\t\tsourceHash,\n\t\t\t\t\t\t\tpublisher: opts.publisher.id,\n\t\t\t\t\t\t\tmvrPlaceholder: opts.mvrPlaceholder ?? null,\n\t\t\t\t\t\t\texcludeFromCodegen: opts.excludeFromCodegen === true,\n\t\t\t\t\t\t\tcapture: opts.capture ?? null,\n\t\t\t\t\t\t\tnetworks: opts.networks ?? null,\n\t\t\t\t\t\t\t// url+rev change → new identity → re-clone + rebuild.\n\t\t\t\t\t\t\tgit: opts.git ?? null,\n\t\t\t\t\t\t})),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tEffect.orDie,\n\t\t\t),\n\t\t),\n\t\twatch: {\n\t\t\t// File-watcher contribution — restart on Move source edits.\n\t\t\t// Distilled doc §Outputs: literal-path Packages contribute\n\t\t\t// watch roots. Effect-resolved paths do NOT auto-attach. A git\n\t\t\t// source lives in the read-only host cache, not the dev tree, so\n\t\t\t// it contributes no watch roots (nothing local to edit).\n\t\t\tpaths:\n\t\t\t\topts.sourcePath !== undefined\n\t\t\t\t\t? [\n\t\t\t\t\t\t\t`${opts.sourcePath}/**/*.move`,\n\t\t\t\t\t\t\t`${opts.sourcePath}/Move.toml`,\n\t\t\t\t\t\t\t`${opts.sourcePath}/Move.lock`,\n\t\t\t\t\t\t]\n\t\t\t\t\t: [],\n\t\t\tcascade: true,\n\t\t},\n\t\t// Stack-free codegen: the `codegen` verb derives this package's\n\t\t// committed-projection decls from config alone, drawing the\n\t\t// `packageId` from the projection resolver (sentinel / pinned). The\n\t\t// bindings emitter compiles a local `sourcePath` verbatim; a git\n\t\t// source's tree is only materialized at acquire, so it contributes no\n\t\t// stub bindings until the source is on disk (the live `.devstack`\n\t\t// overlay carries them when a stack is running).\n\t\tstaticCodegen: makeLocalStaticCodegen({\n\t\t\tname,\n\t\t\tsourcePath: opts.sourcePath ?? null,\n\t\t\tmvrPlaceholder: opts.mvrPlaceholder,\n\t\t\texcluded: opts.excludeFromCodegen ?? false,\n\t\t\tnetworks: opts.networks,\n\t\t\t// Capture KEYS (config-known) so the committed stub carries\n\t\t\t// `resolveValue('package:<name>:objects', '<key>')` references —\n\t\t\t// no live-only `objects` field, no baked object id.\n\t\t\t...(opts.capture !== undefined ? { objectKeys: Object.keys(opts.capture) } : {}),\n\t\t}),\n\t\t// `deps` auto-infers the resolved `{ sui, publisher }` dependency\n\t\t// object; `ctx` arrives via the `PluginContext` service.\n\t\tstart: ({ sui, publisher: publisherAccount }) =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\t// Resolve the build path first: clone a git source into the host\n\t\t\t\t// cache (cache hit after `inputIdentity` already materialized it),\n\t\t\t\t// or use the local `sourcePath` verbatim. Everything below — and\n\t\t\t\t// the contributions derived from `resolved.sourcePath` — then sees\n\t\t\t\t// a plain local directory.\n\t\t\t\tconst sourcePath = yield* resolveSourcePath();\n\t\t\t\tconst ctx = yield* PluginContext;\n\t\t\t\t// Substrate-context primitives: ArtifactPublisher\n\t\t\t\t// is provided by the supervisor's pluginContext;\n\t\t\t\t// ChainProbe is looked up via the StrategyRegistry\n\t\t\t\t// (Sui registered itself there at acquire). The\n\t\t\t\t// PackageRegistry is a per-stack plugin-owned service\n\t\t\t\t// (a self-contained last-write-wins map — see\n\t\t\t\t// `registry.ts`) — every\n\t\t\t\t// package plugin in the stack yields the SAME instance\n\t\t\t\t// via `PackageRegistryService`, so cross-plugin lookups\n\t\t\t\t// stay consistent and warm-restart verify can use the\n\t\t\t\t// previous packageId as a hint.\n\t\t\t\tconst publisher = yield* CacheService;\n\t\t\t\tconst probe = yield* chainProbeFor<SuiProbeKey>(sui.chainId);\n\t\t\t\tconst registry = yield* PackageRegistryService;\n\t\t\t\t// The per-stack CoinRegistry — same instance every plugin in\n\t\t\t\t// the stack yields via `CoinRegistryService` (the boot wiring\n\t\t\t\t// adds it to the plugin context via\n\t\t\t\t// `extendBuiltInPluginContext`). Local publish folds its\n\t\t\t\t// discovered coins into it directly (was the orchestrator's\n\t\t\t\t// `publishResultSink`).\n\t\t\t\tconst coinRegistry = yield* CoinRegistryService;\n\t\t\t\t// ContainerRuntime + the Sui plugin's resolved image feed\n\t\t\t\t// `runMoveBuild`'s path-(b) (`docker run --rm`) build path.\n\t\t\t\t// Sui surfaces `buildImage` on its resolved client; modes\n\t\t\t\t// without an in-stack image (external, live) surface null\n\t\t\t\t// — runMoveBuild then surfaces a typed error from path (c)\n\t\t\t\t// (host CLI not routed).\n\t\t\t\tconst containerRuntime = yield* ContainerRuntimeService;\n\n\t\t\t\t// Build the concrete `PublishExecutor` once per acquire.\n\t\t\t\t// Hands the resolved SuiSdkShim (for `Transaction.build`,\n\t\t\t\t// `executeTransaction`, `waitForTransaction`) and the\n\t\t\t\t// publisher account (for `signAndExecute`) to the executor\n\t\t\t\t// methods; mode-local's produce body drives them.\n\t\t\t\tconst executor = makePublishExecutor({\n\t\t\t\t\tsdk: sui.sdk,\n\t\t\t\t\taccount: publisherAccount,\n\t\t\t\t\truntime: containerRuntime,\n\t\t\t\t\tforkMode: sui.fork !== null,\n\t\t\t\t\t...(sui.buildImage !== null ? { buildImage: sui.buildImage } : {}),\n\t\t\t\t});\n\n\t\t\t\tconst mode = {\n\t\t\t\t\tmode: 'local',\n\t\t\t\t\tpackageName: name,\n\t\t\t\t\tsourcePath,\n\t\t\t\t\tchainId: sui.chainId,\n\t\t\t\t\tpublisherAddress: publisherAccount.address,\n\t\t\t\t\tmvrOverride: opts.mvrPlaceholder,\n\t\t\t\t\t...(capture !== undefined ? { capture } : {}),\n\t\t\t\t\texecutor,\n\t\t\t\t} satisfies PackageMode;\n\n\t\t\t\tconst { resolved, output } = yield* bootPackageService(publisher, probe, registry, mode);\n\n\t\t\t\tconst projected: LocalPackageResolved<Capture> = {\n\t\t\t\t\t...resolved,\n\t\t\t\t\tcaptured: resolved.captured as CapturedPackageValues<Capture>,\n\t\t\t\t\tpublisher: publisherAccount,\n\t\t\t\t\tpublishResult: output,\n\t\t\t\t};\n\t\t\t\t// Emit the resolved package's contributions inline via the\n\t\t\t\t// shared `emitContributions` router. `projected` is the\n\t\t\t\t// just-resolved local value; `makeLocalCapabilities` builds the\n\t\t\t\t// ordered decl list (snapshot, codegen, registry, projection).\n\t\t\t\temitContributions(ctx, makeLocalCapabilities(name, opts, projected));\n\t\t\t\t// Part 2 (custom-kind re-home): on a fresh publish, fold the\n\t\t\t\t// output's coins into the per-stack CoinRegistry DIRECTLY (was\n\t\t\t\t// the orchestrator's `publishResultSink` consuming the now-\n\t\t\t\t// dead `LOCAL_PACKAGE_PUBLISHED` decl). `output` is null on a\n\t\t\t\t// cache hit (verify path), so discovery is skipped then — the\n\t\t\t\t// registry was already populated on the fresh-publish run that\n\t\t\t\t// seeded the cache.\n\t\t\t\tif (output !== null) {\n\t\t\t\t\tyield* discoverPublishedCoins(coinRegistry, name, projected.packageId, output);\n\t\t\t\t}\n\t\t\t\treturn projected;\n\t\t\t}),\n\t});\n};\n\nconst buildKnownPlugin = <Name extends string>(name: Name, opts: KnownPackageOptions) => {\n\tconst packageRef = resource<PackageResourceId<Name>, KnownPackageResolved>(\n\t\tpackageResourceId(name),\n\t);\n\treturn definePlugin({\n\t\tid: packageRef.id,\n\t\tdependsOn: { sui: suiResource },\n\t\trole: 'task',\n\t\tsection: 'package',\n\t\tinputIdentity: staticInputIdentity({\n\t\t\tplugin: 'package',\n\t\t\tkind: 'known',\n\t\t\tname,\n\t\t\tpackageId: opts.packageId,\n\t\t\tupgradeCapId: opts.upgradeCapId ?? null,\n\t\t\tmvrPlaceholder: opts.mvrPlaceholder ?? null,\n\t\t\tnetworks: opts.networks ?? null,\n\t\t}),\n\t\t// Stack-free codegen: a known package's `packageId` is already a\n\t\t// config literal, so the committed stub emits it verbatim (no chain\n\t\t// contact, no sentinel substitution).\n\t\tstaticCodegen: makeKnownStaticCodegen({\n\t\t\tname,\n\t\t\tpackageId: opts.packageId,\n\t\t\tmvrPlaceholder: opts.mvrPlaceholder,\n\t\t\t...(opts.upgradeCapId !== undefined ? { upgradeCapId: opts.upgradeCapId } : {}),\n\t\t\tnetworks: opts.networks,\n\t\t}),\n\t\tstart: ({ sui }) =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst ctx = yield* PluginContext;\n\t\t\t\tconst publisher = yield* CacheService;\n\t\t\t\tconst probe = yield* chainProbeFor<SuiProbeKey>(sui.chainId);\n\t\t\t\tconst registry = yield* PackageRegistryService;\n\t\t\t\tconst mode = {\n\t\t\t\t\tmode: 'known',\n\t\t\t\t\tpackageName: name,\n\t\t\t\t\tpackageId: opts.packageId,\n\t\t\t\t\tupgradeCapId: opts.upgradeCapId,\n\t\t\t\t\tmvrOverride: opts.mvrPlaceholder,\n\t\t\t\t} satisfies PackageMode;\n\t\t\t\tconst { resolved } = yield* bootPackageService(publisher, probe, registry, mode);\n\t\t\t\t// Emit the resolved package's contributions inline via the\n\t\t\t\t// shared `emitContributions` router. `makeKnownCapabilities`\n\t\t\t\t// builds the ordered decl list (snapshot, codegen, registry,\n\t\t\t\t// projection).\n\t\t\t\temitContributions(ctx, makeKnownCapabilities(name, opts, resolved));\n\t\t\t\t// Known mode never publishes — no output to walk, so\n\t\t\t\t// the coin-discovery hook is skipped here. Users who\n\t\t\t\t// want coin records for a knownPackage point a\n\t\t\t\t// `coin.known('0xPKG::module::Witness')` at the\n\t\t\t\t// fully-qualified type directly; the bare-type path\n\t\t\t\t// hits the live RPC for metadata rather than the\n\t\t\t\t// output-walker.\n\t\t\t\treturn resolved;\n\t\t\t}),\n\t});\n};\n\n// ---------------------------------------------------------------------------\n// Capability builders — pure helpers returning the ordered decl list.\n//\n// The package `start` bodies feed these into the shared `emitContributions`\n// router after resolving the value. Decl shapes + emit ORDER are load-bearing.\n//\n// NOTE: the LOCAL builder does NOT append a custom published-coin decl.\n// Coin discovery runs DIRECTLY in the local `start` body (see\n// `discoverPublishedCoins`); appending a decl here would double-discover.\n// ---------------------------------------------------------------------------\n\nconst makeLocalCapabilities = (\n\tname: string,\n\topts: { readonly excludeFromCodegen?: boolean; readonly networks?: PackageNetworks },\n\tresolved: LocalPackageResolved,\n): ReadonlyArray<Contribution> => {\n\t// Snapshot + codegen lift their typed fields off the resolved\n\t// publish (real packageId + captured object ids). The static-form\n\t// placeholders are gone.\n\tconst snap: SnapshotableDecl = makeSnapshotable(\n\t\tname,\n\t\tresolved.publishResult?.packageId ?? resolved.packageId,\n\t);\n\tconst codegen: CodegenableDecl<'package'> = makeLocalCodegenable(\n\t\t{\n\t\t\tkind: 'local',\n\t\t\tname,\n\t\t\tpackageId: resolved.packageId,\n\t\t\tupgradeCapId: resolved.upgradeCapId,\n\t\t\tsourcePath: resolved.sourcePath,\n\t\t\tmvrPlaceholder: resolved.mvrPlaceholder,\n\t\t\tcaptured: resolved.captured,\n\t\t},\n\t\t{\n\t\t\texcluded: opts.excludeFromCodegen ?? false,\n\t\t\t...(opts.networks !== undefined ? { networks: opts.networks } : {}),\n\t\t},\n\t);\n\t// The plugin contributes to the package-registry strategy under a\n\t// fixed key — the substrate orchestrator wires all packages'\n\t// contributions into the same per-stack registry.\n\tconst projection: PackageRegistryProjectionContribution = {\n\t\tkind: 'local',\n\t\tname,\n\t\tpackageId: resolved.packageId,\n\t\tupgradeCapId: resolved.upgradeCapId ?? null,\n\t\tmvrPlaceholder: resolved.mvrPlaceholder,\n\t\tsourcePath: resolved.sourcePath,\n\t};\n\tconst registryContribution: StrategyContributorDecl<\n\t\ttypeof PACKAGE_REGISTRY_CAPABILITY_KEY,\n\t\tPackageRegistryProjectionContribution\n\t> = {\n\t\tkind: 'strategy-contributor',\n\t\tcapabilityKey: PACKAGE_REGISTRY_CAPABILITY_KEY,\n\t\tstrategy: projection,\n\t\tautoMounted: true,\n\t};\n\treturn [snap, codegen, registryContribution, makePackageProjectionContribution(projection)];\n};\n\nconst makeKnownCapabilities = (\n\tname: string,\n\topts: KnownPackageOptions,\n\tresolved: KnownPackageResolved,\n): ReadonlyArray<Contribution> => {\n\tconst snap: SnapshotableDecl = makeSnapshotable(name, `known:${resolved.packageId}`);\n\tconst codegen: CodegenableDecl<'package'> = makeKnownCodegenable(\n\t\t{\n\t\t\tkind: 'known',\n\t\t\tname,\n\t\t\tpackageId: resolved.packageId,\n\t\t\tupgradeCapId: resolved.upgradeCapId ?? opts.upgradeCapId,\n\t\t\tmvrPlaceholder: resolved.mvrPlaceholder,\n\t\t},\n\t\topts.networks !== undefined ? { networks: opts.networks } : {},\n\t);\n\tconst projection: PackageRegistryProjectionContribution = {\n\t\tkind: 'known',\n\t\tname,\n\t\tpackageId: resolved.packageId,\n\t\tupgradeCapId: resolved.upgradeCapId ?? opts.upgradeCapId ?? null,\n\t\tmvrPlaceholder: resolved.mvrPlaceholder,\n\t\tsourcePath: null,\n\t};\n\tconst registryContribution: StrategyContributorDecl<\n\t\ttypeof PACKAGE_REGISTRY_CAPABILITY_KEY,\n\t\tPackageRegistryProjectionContribution\n\t> = {\n\t\tkind: 'strategy-contributor',\n\t\tcapabilityKey: PACKAGE_REGISTRY_CAPABILITY_KEY,\n\t\tstrategy: projection,\n\t\tautoMounted: true,\n\t};\n\treturn [snap, codegen, registryContribution, makePackageProjectionContribution(projection)];\n};\n\n/** Fold a fresh local-package publish output into the per-stack\n * `CoinRegistry`. Lifted VERBATIM from the orchestrator's former\n * `publishResultSink` (orchestrators/boot.ts): the same\n * `discoverCoinsFromPublish` walk + the same `CoinRecord` projection\n * (including the publisher-owns-cap gate on `treasuryCapId`).\n *\n * Re-homing this into the local `start` body — AFTER the publish output\n * is known, BEFORE `start` returns — preserves discovery timing: the\n * coin plugin `dependsOn` package, so it acquires only after package\n * readies, by which point the registry is already populated. The\n * previous decl-driven sink ran at the same point in the lifecycle\n * (post-`start` dispatch), so consumers see no ordering change. */\nexport const discoverPublishedCoins = (\n\tcoinRegistry: CoinRegistry,\n\tpackageName: string,\n\tpackageId: string,\n\toutput: LocalPackagePublishOutput,\n): Effect.Effect<void> =>\n\tEffect.gen(function* () {\n\t\tfor (const discovered of discoverCoinsFromPublish(output)) {\n\t\t\tconst record: CoinRecord = {\n\t\t\t\tkey: (discovered.symbol ?? discovered.witness).toLowerCase(),\n\t\t\t\ttype: discovered.fullCoinType,\n\t\t\t\twitness: discovered.witness,\n\t\t\t\tmoduleName: discovered.moduleName,\n\t\t\t\tdecimals: discovered.decimals ?? 0,\n\t\t\t\t...(discovered.symbol === undefined ? {} : { symbol: discovered.symbol }),\n\t\t\t\t...(discovered.displayName === undefined ? {} : { displayName: discovered.displayName }),\n\t\t\t\t...(discovered.iconUrl === undefined ? {} : { iconUrl: discovered.iconUrl }),\n\t\t\t\t...(!discovered.publisherOwnsCap || discovered.treasuryCapId === undefined\n\t\t\t\t\t? {}\n\t\t\t\t\t: { treasuryCapId: discovered.treasuryCapId }),\n\t\t\t\t...(discovered.metadataId === undefined ? {} : { metadataId: discovered.metadataId }),\n\t\t\t\tpackageId,\n\t\t\t\tpublishingPackageName: packageName,\n\t\t\t};\n\t\t\tyield* coinRegistry.register(record);\n\t\t}\n\t});\n\n// ---------------------------------------------------------------------------\n// Public factories\n// ---------------------------------------------------------------------------\n\n/** Build + publish a local Move package. The resolved value is\n * `LocalPackageResolved` so consumers that need bindings / source\n * path are typed correctly.\n *\n * Required `opts.publisher`: the account that signs the publish tx.\n * Pass the same `account('alice')` reference used elsewhere in the\n * stack — the package.s `dependsOn` includes `account/<publisher>`\n * so the substrate orders the publisher's keypair + funding strictly\n * before publish. */\nexport const localPackage = <\n\tName extends string,\n\tconst Publisher extends PublisherAccountMember,\n\tconst Capture extends PackageCapture | undefined = undefined,\n>(\n\tname: Name,\n\topts: LocalPackageOptions<Publisher, Capture>,\n) => buildLocalPlugin(name, opts);\n\n/** Verify-only against a fixed on-chain package id. The resolved\n * value is `KnownPackageResolved` — narrower than local, so the\n * bindings emitter rejects this at compose time. */\nexport const knownPackage = <Name extends string>(name: Name, opts: KnownPackageOptions) =>\n\tbuildKnownPlugin(name, opts);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/plugins/package/index.ts"],"sourcesContent":["// Package plugin — barrel + factories.\n//\n// Architecture: Package is the canonical implementation of the\n// `ArtifactPublisher` substrate primitive. Many service\n// plugins depend on its publish output (Coin types, Walrus/Seal/\n// Deepbook contracts, Action outputs).\n//\n// Public surface:\n//\n// - `localPackage(name, opts)` — build + publish a Move source tree.\n// - `knownPackage(name, opts)` — verify-only against a fixed id.\n//\n// Type split (distilled doc Invariant 9): `localPackage` resolves to\n// `LocalPackage`; `knownPackage` resolves to `KnownPackage`. The\n// bindings emitter (in the codegen orchestrator) types-out KnownPackage\n// at compose time, so misuse fails at compile time rather than at\n// emit time.\n//\n// Resource id: `'package:<name>'` — one tag per user-declared package\n// (the symbolic name is part of the identity so two `localPackage`\n// calls in the same stack don't collide on the substrate's tag\n// registry). Substrate-side plugin key is the same string.\n\nimport { Effect } from 'effect';\n\nimport { projection } from '../../api/define-capabilities.ts';\nimport {\n\tcomputedInputIdentity,\n\tdefinePlugin,\n\tresource,\n\tstaticInputIdentity,\n\ttype ResourceRef,\n} from '../../api/define-plugin.ts';\nimport type { Contribution } from '../../substrate/plugin-ctx.ts';\nimport type { CodegenableDecl } from '../../contracts/codegenable.ts';\nimport type { ProjectionDecl } from '../../contracts/projection.ts';\nimport { pickCreatedByType, type LocalPackagePublishOutput } from './publish-output.ts';\nimport type { SnapshotableDecl } from '../../contracts/snapshotable.ts';\nimport type { StrategyContributorDecl } from '../../contracts/strategy-contributor.ts';\nimport { emitContributions, PluginContext } from '../../substrate/plugin-ctx.ts';\nimport { ContainerRuntimeService } from '../../runtime/docker/service.ts';\nimport {\n\tCoinRegistryService,\n\tdiscoverCoinsFromPublish,\n\ttype CoinRecord,\n\ttype CoinRegistry,\n} from '../coin/index.ts';\nimport { CacheService } from '../../substrate/runtime/cache/index.ts';\nimport { chainProbeFor } from '../../substrate/runtime/strategy-registry/index.ts';\nimport { suiResource, type SuiProbeKey } from '../sui/index.ts';\nimport type { AccountResourceId, AccountValue } from '../account/index.ts';\nimport {\n\tmakeKnownCodegenable,\n\tmakeKnownStaticCodegen,\n\tmakeLocalCodegenable,\n\tmakeLocalStaticCodegen,\n} from './codegen.ts';\nimport { hashMoveSources } from './build.ts';\nimport type { PublishError } from './errors.ts';\nimport { materializeGitSource, type GitSource } from './git-source.ts';\nimport { makePublishExecutor } from './publish-executor.ts';\nimport { bootPackageService, type PackageMode } from './service.ts';\nimport {\n\tPACKAGE_REGISTRY_CAPABILITY_KEY,\n\tPackageRegistryService,\n\ttype ResolvedKnownPackage,\n\ttype ResolvedLocalPackage,\n} from './registry.ts';\nimport { makeSnapshotable } from './snapshot.ts';\n\n// ---------------------------------------------------------------------------\n// Publisher account ref — explicit upstream\n// ---------------------------------------------------------------------------\n\n/** A user-supplied publisher account ref. The user passes the result\n * of `account('alice')` — NOT a bare string. Generic over the\n * literal account name so the package dependency preserves the\n * per-account resource id. */\nexport type PublisherAccountMember<Name extends string = string> = ResourceRef<\n\tAccountResourceId<Name>,\n\tAccountValue\n>;\n\n// ---------------------------------------------------------------------------\n// Resource — one per declared package, keyed by symbolic name\n// ---------------------------------------------------------------------------\n\n/** Resource id constructor. The symbolic package name is part of the tag\n * identity so the substrate's compose-time dedup detects collisions\n * cleanly (two `localPackage('foo', ...)` calls in one stack → typed\n * error at compose time). */\nexport const packageResourceId = <Name extends string>(name: Name): `package:${Name}` =>\n\t`package:${name}`;\n\n/** The literal-template resource id for a package by symbolic name. */\nexport type PackageResourceId<Name extends string> = `package:${Name}`;\n\n/** Public resolved value shapes — re-exported from `registry.ts` to\n * give consumers one stable import path. */\nexport type { ResolvedLocalPackage, ResolvedKnownPackage, ResolvedPackage } from './registry.ts';\nexport type {\n\tPickCreatedByTypeOptions,\n\tLocalPackagePublishOutput,\n\tPackagePublishObjectChange,\n} from './publish-output.ts';\nexport { pickCreatedByType } from './publish-output.ts';\nexport type { PublishError } from './errors.ts';\nexport type { PackageBindings } from './codegen.ts';\nexport type { PublishExecutor } from './mode-local.ts';\n\n/** Resolved value carried by the package resource. Local packages also\n * expose the publish output so manifest emitters and capture-spec\n * callers can read it. Sibling plugin folds consume the package-owned\n * extension contribution instead of importing package internals. */\nexport type PackageCaptureMap = Readonly<Record<string, string>>;\n\ntype PackageCaptureCallback = (\n\toutput: LocalPackagePublishOutput,\n) => Readonly<Record<string, string>>;\n\nexport type PackageCapture = PackageCaptureMap;\n\nexport type CapturedPackageValues<Capture> = Capture extends PackageCaptureCallback\n\t? Readonly<Record<string, string>>\n\t: Capture extends PackageCaptureMap\n\t\t? { readonly [K in keyof Capture]: string }\n\t\t: Readonly<Record<string, string>>;\n\nexport interface LocalPackageResolved<Capture = undefined> extends Omit<\n\tResolvedLocalPackage,\n\t'captured'\n> {\n\t/** Captured object ids keyed by the user's `capture` option. */\n\treadonly captured: CapturedPackageValues<Capture>;\n\t/** Publisher account that signed this package. Kept on the live\n\t * resource value so downstream local coin plugins can mint from\n\t * publisher-owned TreasuryCaps through the centralized funding\n\t * strategy path. It is intentionally not written to generated\n\t * bindings or the package registry. */\n\treadonly publisher: AccountValue;\n\t/** Publish output — present after a fresh publish, null on\n\t * cache hit (verify-only path). Consumers that need the\n\t * output MUST tolerate null and fall back to chain reads via\n\t * the ChainProbe. */\n\treadonly publishResult: LocalPackagePublishOutput | null;\n}\n\nexport type KnownPackageResolved = ResolvedKnownPackage;\n\nexport type PackageResolved = LocalPackageResolved | KnownPackageResolved;\n\n// ---------------------------------------------------------------------------\n// Factory options\n// ---------------------------------------------------------------------------\n\nexport interface LocalPackageOptions<\n\tPublisher extends PublisherAccountMember = PublisherAccountMember,\n\tCapture extends PackageCapture | undefined = undefined,\n> {\n\t/** Local on-disk path to the Move package. Provide EXACTLY ONE of\n\t * `sourcePath` or `git`. */\n\treadonly sourcePath?: string;\n\t/** Remote git source — clone a repo and build a sub-path of it instead of\n\t * vendoring the Move tree. Cloned once into a host cache keyed by\n\t * `url + rev` (see `git-source.ts`); pin `rev` to a commit SHA or tag for\n\t * reproducibility. Mutually exclusive with `sourcePath`. */\n\treadonly git?: GitSource;\n\treadonly mvrPlaceholder?: string;\n\treadonly excludeFromCodegen?: boolean;\n\t/** Move datatypes (struct / enum) to expose as MVR `types` overrides.\n\t * OPT-IN: each entry is a `'<module>::<Name>'` relative to THIS package\n\t * (the `@local/<slug>` prefix is implied), e.g. `['game::Lobby',\n\t * 'game::Game']`. Each declared type emits one\n\t * `mvrOverrides.types['@local/<slug>::<module>::<Name>']` entry whose value\n\t * resolves per-network to `` `${requireId(dep, \"@local/<slug>\")}::<module>::<Name>` ``\n\t * (the resolved package id, never baked). Absent / empty ⇒ `types: {}` — we\n\t * do NOT auto-enumerate every package type (that balloons the config + every\n\t * committed `deployments/<net>.ts`). */\n\treadonly mvrTypes?: readonly string[];\n\t/** Capture created objects from the publish output. The record\n\t * form maps output keys to object-type suffixes, e.g.\n\t * `{ boardId: '::board::Board' }`. */\n\treadonly capture?: Capture;\n\t/** Publisher account — the signer for the publish tx. Pass the\n\t * result of `account('alice')` (the same plugin/resource ref used\n\t * in the rest of the stack — NOT a duplicate factory call).\n\t *\n\t * Required for local packages: a publish tx must be signed by\n\t * SOMEONE; we make the choice explicit so two packages in the\n\t * same stack can publish under different accounts (no implicit\n\t * \"first account\" convention to memorise). Distilled doc Invariant\n\t * 4 — \"Signer MUST be an explicit upstream\". */\n\treadonly publisher: Publisher;\n}\n\nexport interface KnownPackageOptions {\n\treadonly packageId: string;\n\treadonly upgradeCapId?: string;\n\treadonly mvrPlaceholder?: string;\n\t/** Move datatypes (struct / enum) to expose as MVR `types` overrides —\n\t * see {@link LocalPackageOptions.mvrTypes}. Each entry is a\n\t * `'<module>::<Name>'` relative to this package; OPT-IN, defaults to none. */\n\treadonly mvrTypes?: readonly string[];\n}\n\ninterface PackageRegistryProjectionContribution {\n\treadonly kind: 'local' | 'known';\n\treadonly name: string;\n\treadonly packageId: string;\n\treadonly upgradeCapId: string | null;\n\treadonly mvrPlaceholder: string;\n\treadonly sourcePath: string | null;\n}\n\nconst makePackageProjectionContribution = (\n\tcontribution: PackageRegistryProjectionContribution,\n): ProjectionDecl => {\n\tconst updatedAt = Date.now();\n\tconst key = `package/${contribution.name}` as `package/${string}`;\n\treturn projection({\n\t\tkind: 'package',\n\t\tkey,\n\t\tpayload: {\n\t\t\tkey,\n\t\t\trowKey: null,\n\t\t\tname: contribution.name,\n\t\t\tkind: contribution.kind,\n\t\t\tpackageId: contribution.packageId,\n\t\t\tupgradeCapId: contribution.upgradeCapId,\n\t\t\tmvrPlaceholder: contribution.mvrPlaceholder,\n\t\t\tsourcePath: contribution.sourcePath,\n\t\t\tupdatedAt,\n\t\t},\n\t\tat: updatedAt,\n\t});\n};\n\n// ---------------------------------------------------------------------------\n// Internal builders\n// ---------------------------------------------------------------------------\n\nconst normalizeCapture = <Capture extends PackageCapture | undefined>(\n\tpackageName: string,\n\tcapture: Capture,\n): PackageCaptureCallback | undefined => {\n\tif (capture === undefined) return undefined;\n\treturn (output) => {\n\t\tconst captured: Record<string, string> = {};\n\t\tfor (const [key, suffix] of Object.entries(capture)) {\n\t\t\tconst objectId = pickCreatedByType(output.objectChanges, { suffix });\n\t\t\tif (objectId === undefined) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`localPackage('${packageName}') capture '${key}' matched no created object with suffix '${suffix}'.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tcaptured[key] = objectId;\n\t\t}\n\t\treturn captured;\n\t};\n};\n\nconst buildLocalPlugin = <\n\tName extends string,\n\tconst Publisher extends PublisherAccountMember,\n\tCapture extends PackageCapture | undefined,\n>(\n\tname: Name,\n\topts: LocalPackageOptions<Publisher, Capture>,\n) => {\n\tconst packageRef = resource<PackageResourceId<Name>, LocalPackageResolved<Capture>>(\n\t\tpackageResourceId(name),\n\t);\n\tconst capture = normalizeCapture(name, opts.capture);\n\n\t// Exactly one source is required. Validated at config-evaluation time (like\n\t// `normalizeCapture`) so a typo surfaces immediately, not mid-boot.\n\tif (opts.sourcePath === undefined && opts.git === undefined) {\n\t\tthrow new Error(`localPackage('${name}'): provide either 'sourcePath' or 'git'.`);\n\t}\n\tif (opts.sourcePath !== undefined && opts.git !== undefined) {\n\t\tthrow new Error(`localPackage('${name}'): 'sourcePath' and 'git' are mutually exclusive.`);\n\t}\n\n\t// Resolve the on-disk path to build from: a local `sourcePath` is used\n\t// verbatim; a `git` source is cloned into the host cache (idempotent —\n\t// see `materializeGitSource`) and the cached path returned. Called from\n\t// both `inputIdentity` and `start`; the second call is a cache hit.\n\tconst resolveSourcePath = (): Effect.Effect<string, PublishError> =>\n\t\topts.git !== undefined\n\t\t\t? materializeGitSource(opts.git, name)\n\t\t\t: Effect.succeed(opts.sourcePath as string);\n\n\treturn definePlugin({\n\t\tid: packageRef.id,\n\t\tdependsOn: { sui: suiResource, publisher: opts.publisher },\n\t\trole: 'task',\n\t\tsection: 'package',\n\t\tinputIdentity: computedInputIdentity(() =>\n\t\t\tresolveSourcePath().pipe(\n\t\t\t\tEffect.flatMap((sourcePath) =>\n\t\t\t\t\thashMoveSources(sourcePath).pipe(\n\t\t\t\t\t\tEffect.map((sourceHash) => ({\n\t\t\t\t\t\t\tplugin: 'package',\n\t\t\t\t\t\t\tkind: 'local',\n\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\t// The MATERIALIZED path: for a git source this is the\n\t\t\t\t\t\t\t// cache dir, so the hash + identity reflect what is built.\n\t\t\t\t\t\t\tsourcePath,\n\t\t\t\t\t\t\tsourceHash,\n\t\t\t\t\t\t\tpublisher: opts.publisher.id,\n\t\t\t\t\t\t\tmvrPlaceholder: opts.mvrPlaceholder ?? null,\n\t\t\t\t\t\t\tmvrTypes: opts.mvrTypes ?? null,\n\t\t\t\t\t\t\texcludeFromCodegen: opts.excludeFromCodegen === true,\n\t\t\t\t\t\t\tcapture: opts.capture ?? null,\n\t\t\t\t\t\t\t// url+rev change → new identity → re-clone + rebuild.\n\t\t\t\t\t\t\tgit: opts.git ?? null,\n\t\t\t\t\t\t})),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\tEffect.orDie,\n\t\t\t),\n\t\t),\n\t\twatch: {\n\t\t\t// File-watcher contribution — restart on Move source edits.\n\t\t\t// Distilled doc §Outputs: literal-path Packages contribute\n\t\t\t// watch roots. Effect-resolved paths do NOT auto-attach. A git\n\t\t\t// source lives in the read-only host cache, not the dev tree, so\n\t\t\t// it contributes no watch roots (nothing local to edit).\n\t\t\tpaths:\n\t\t\t\topts.sourcePath !== undefined\n\t\t\t\t\t? [\n\t\t\t\t\t\t\t`${opts.sourcePath}/**/*.move`,\n\t\t\t\t\t\t\t`${opts.sourcePath}/Move.toml`,\n\t\t\t\t\t\t\t`${opts.sourcePath}/Move.lock`,\n\t\t\t\t\t\t]\n\t\t\t\t\t: [],\n\t\t\tcascade: true,\n\t\t},\n\t\t// Stack-free codegen: the `codegen` verb derives this package's\n\t\t// committed-projection decls from config alone, drawing the\n\t\t// `packageId` from the projection resolver (sentinel / pinned). The\n\t\t// bindings emitter compiles a local `sourcePath` verbatim; a git\n\t\t// source's tree is only materialized at acquire, so it contributes no\n\t\t// stub bindings until the source is on disk (the live `.devstack`\n\t\t// overlay carries them when a stack is running).\n\t\tstaticCodegen: makeLocalStaticCodegen({\n\t\t\tname,\n\t\t\tsourcePath: opts.sourcePath ?? null,\n\t\t\tmvrPlaceholder: opts.mvrPlaceholder,\n\t\t\texcluded: opts.excludeFromCodegen ?? false,\n\t\t\t...(opts.mvrTypes !== undefined ? { mvrTypes: opts.mvrTypes } : {}),\n\t\t\t// Capture KEYS (config-known) so the committed stub carries\n\t\t\t// `requireValue(dep, 'package:<name>:objects', '<key>')` references —\n\t\t\t// no live-only `objects` field, no baked object id.\n\t\t\t...(opts.capture !== undefined ? { objectKeys: Object.keys(opts.capture) } : {}),\n\t\t}),\n\t\t// `deps` auto-infers the resolved `{ sui, publisher }` dependency\n\t\t// object; `ctx` arrives via the `PluginContext` service.\n\t\tstart: ({ sui, publisher: publisherAccount }) =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\t// Resolve the build path first: clone a git source into the host\n\t\t\t\t// cache (cache hit after `inputIdentity` already materialized it),\n\t\t\t\t// or use the local `sourcePath` verbatim. Everything below — and\n\t\t\t\t// the contributions derived from `resolved.sourcePath` — then sees\n\t\t\t\t// a plain local directory.\n\t\t\t\tconst sourcePath = yield* resolveSourcePath();\n\t\t\t\tconst ctx = yield* PluginContext;\n\t\t\t\t// Substrate-context primitives: ArtifactPublisher\n\t\t\t\t// is provided by the supervisor's pluginContext;\n\t\t\t\t// ChainProbe is looked up via the StrategyRegistry\n\t\t\t\t// (Sui registered itself there at acquire). The\n\t\t\t\t// PackageRegistry is a per-stack plugin-owned service\n\t\t\t\t// (a self-contained last-write-wins map — see\n\t\t\t\t// `registry.ts`) — every\n\t\t\t\t// package plugin in the stack yields the SAME instance\n\t\t\t\t// via `PackageRegistryService`, so cross-plugin lookups\n\t\t\t\t// stay consistent and warm-restart verify can use the\n\t\t\t\t// previous packageId as a hint.\n\t\t\t\tconst publisher = yield* CacheService;\n\t\t\t\tconst probe = yield* chainProbeFor<SuiProbeKey>(sui.chainId);\n\t\t\t\tconst registry = yield* PackageRegistryService;\n\t\t\t\t// The per-stack CoinRegistry — same instance every plugin in\n\t\t\t\t// the stack yields via `CoinRegistryService` (the boot wiring\n\t\t\t\t// adds it to the plugin context via\n\t\t\t\t// `extendBuiltInPluginContext`). Local publish folds its\n\t\t\t\t// discovered coins into it directly (was the orchestrator's\n\t\t\t\t// `publishResultSink`).\n\t\t\t\tconst coinRegistry = yield* CoinRegistryService;\n\t\t\t\t// ContainerRuntime + the Sui plugin's resolved image feed\n\t\t\t\t// `runMoveBuild`'s path-(b) (`docker run --rm`) build path.\n\t\t\t\t// Sui surfaces `buildImage` on its resolved client; modes\n\t\t\t\t// without an in-stack image (external, live) surface null\n\t\t\t\t// — runMoveBuild then surfaces a typed error from path (c)\n\t\t\t\t// (host CLI not routed).\n\t\t\t\tconst containerRuntime = yield* ContainerRuntimeService;\n\n\t\t\t\t// Build the concrete `PublishExecutor` once per acquire.\n\t\t\t\t// Hands the resolved SuiSdkShim (for `Transaction.build`,\n\t\t\t\t// `executeTransaction`, `waitForTransaction`) and the\n\t\t\t\t// publisher account (for `signAndExecute`) to the executor\n\t\t\t\t// methods; mode-local's produce body drives them.\n\t\t\t\tconst executor = makePublishExecutor({\n\t\t\t\t\tsdk: sui.sdk,\n\t\t\t\t\taccount: publisherAccount,\n\t\t\t\t\truntime: containerRuntime,\n\t\t\t\t\tforkMode: sui.fork !== null,\n\t\t\t\t\t...(sui.buildImage !== null ? { buildImage: sui.buildImage } : {}),\n\t\t\t\t});\n\n\t\t\t\tconst mode = {\n\t\t\t\t\tmode: 'local',\n\t\t\t\t\tpackageName: name,\n\t\t\t\t\tsourcePath,\n\t\t\t\t\tchainId: sui.chainId,\n\t\t\t\t\tpublisherAddress: publisherAccount.address,\n\t\t\t\t\tmvrOverride: opts.mvrPlaceholder,\n\t\t\t\t\t...(capture !== undefined ? { capture } : {}),\n\t\t\t\t\texecutor,\n\t\t\t\t} satisfies PackageMode;\n\n\t\t\t\tconst { resolved, output } = yield* bootPackageService(publisher, probe, registry, mode);\n\n\t\t\t\tconst projected: LocalPackageResolved<Capture> = {\n\t\t\t\t\t...resolved,\n\t\t\t\t\tcaptured: resolved.captured as CapturedPackageValues<Capture>,\n\t\t\t\t\tpublisher: publisherAccount,\n\t\t\t\t\tpublishResult: output,\n\t\t\t\t};\n\t\t\t\t// Emit the resolved package's contributions inline via the\n\t\t\t\t// shared `emitContributions` router. `projected` is the\n\t\t\t\t// just-resolved local value; `makeLocalCapabilities` builds the\n\t\t\t\t// ordered decl list (snapshot, codegen, registry, projection).\n\t\t\t\temitContributions(ctx, makeLocalCapabilities(name, opts, projected));\n\t\t\t\t// Part 2 (custom-kind re-home): on a fresh publish, fold the\n\t\t\t\t// output's coins into the per-stack CoinRegistry DIRECTLY (was\n\t\t\t\t// the orchestrator's `publishResultSink` consuming the now-\n\t\t\t\t// dead `LOCAL_PACKAGE_PUBLISHED` decl). `output` is null on a\n\t\t\t\t// cache hit (verify path), so discovery is skipped then — the\n\t\t\t\t// registry was already populated on the fresh-publish run that\n\t\t\t\t// seeded the cache.\n\t\t\t\tif (output !== null) {\n\t\t\t\t\tyield* discoverPublishedCoins(coinRegistry, name, projected.packageId, output);\n\t\t\t\t}\n\t\t\t\treturn projected;\n\t\t\t}),\n\t});\n};\n\nconst buildKnownPlugin = <Name extends string>(name: Name, opts: KnownPackageOptions) => {\n\tconst packageRef = resource<PackageResourceId<Name>, KnownPackageResolved>(\n\t\tpackageResourceId(name),\n\t);\n\treturn definePlugin({\n\t\tid: packageRef.id,\n\t\tdependsOn: { sui: suiResource },\n\t\trole: 'task',\n\t\tsection: 'package',\n\t\tinputIdentity: staticInputIdentity({\n\t\t\tplugin: 'package',\n\t\t\tkind: 'known',\n\t\t\tname,\n\t\t\tpackageId: opts.packageId,\n\t\t\tupgradeCapId: opts.upgradeCapId ?? null,\n\t\t\tmvrPlaceholder: opts.mvrPlaceholder ?? null,\n\t\t}),\n\t\t// Stack-free codegen: a known package's `packageId` is already a\n\t\t// config literal, so the committed stub emits it verbatim (no chain\n\t\t// contact, no sentinel substitution).\n\t\tstaticCodegen: makeKnownStaticCodegen({\n\t\t\tname,\n\t\t\tpackageId: opts.packageId,\n\t\t\tmvrPlaceholder: opts.mvrPlaceholder,\n\t\t\t...(opts.upgradeCapId !== undefined ? { upgradeCapId: opts.upgradeCapId } : {}),\n\t\t\t...(opts.mvrTypes !== undefined ? { mvrTypes: opts.mvrTypes } : {}),\n\t\t}),\n\t\tstart: ({ sui }) =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst ctx = yield* PluginContext;\n\t\t\t\tconst publisher = yield* CacheService;\n\t\t\t\tconst probe = yield* chainProbeFor<SuiProbeKey>(sui.chainId);\n\t\t\t\tconst registry = yield* PackageRegistryService;\n\t\t\t\tconst mode = {\n\t\t\t\t\tmode: 'known',\n\t\t\t\t\tpackageName: name,\n\t\t\t\t\tpackageId: opts.packageId,\n\t\t\t\t\tupgradeCapId: opts.upgradeCapId,\n\t\t\t\t\tmvrOverride: opts.mvrPlaceholder,\n\t\t\t\t} satisfies PackageMode;\n\t\t\t\tconst { resolved } = yield* bootPackageService(publisher, probe, registry, mode);\n\t\t\t\t// Emit the resolved package's contributions inline via the\n\t\t\t\t// shared `emitContributions` router. `makeKnownCapabilities`\n\t\t\t\t// builds the ordered decl list (snapshot, codegen, registry,\n\t\t\t\t// projection).\n\t\t\t\temitContributions(ctx, makeKnownCapabilities(name, opts, resolved));\n\t\t\t\t// Known mode never publishes — no output to walk, so\n\t\t\t\t// the coin-discovery hook is skipped here. Users who\n\t\t\t\t// want coin records for a knownPackage point a\n\t\t\t\t// `coin.known('0xPKG::module::Witness')` at the\n\t\t\t\t// fully-qualified type directly; the bare-type path\n\t\t\t\t// hits the live RPC for metadata rather than the\n\t\t\t\t// output-walker.\n\t\t\t\treturn resolved;\n\t\t\t}),\n\t});\n};\n\n// ---------------------------------------------------------------------------\n// Capability builders — pure helpers returning the ordered decl list.\n//\n// The package `start` bodies feed these into the shared `emitContributions`\n// router after resolving the value. Decl shapes + emit ORDER are load-bearing.\n//\n// NOTE: the LOCAL builder does NOT append a custom published-coin decl.\n// Coin discovery runs DIRECTLY in the local `start` body (see\n// `discoverPublishedCoins`); appending a decl here would double-discover.\n// ---------------------------------------------------------------------------\n\nconst makeLocalCapabilities = (\n\tname: string,\n\topts: { readonly excludeFromCodegen?: boolean; readonly mvrTypes?: readonly string[] },\n\tresolved: LocalPackageResolved,\n): ReadonlyArray<Contribution> => {\n\t// Snapshot + codegen lift their typed fields off the resolved\n\t// publish (real packageId + captured object ids). The static-form\n\t// placeholders are gone.\n\tconst snap: SnapshotableDecl = makeSnapshotable(\n\t\tname,\n\t\tresolved.publishResult?.packageId ?? resolved.packageId,\n\t);\n\tconst codegen: CodegenableDecl<'package'> = makeLocalCodegenable(\n\t\t{\n\t\t\tkind: 'local',\n\t\t\tname,\n\t\t\tpackageId: resolved.packageId,\n\t\t\tupgradeCapId: resolved.upgradeCapId,\n\t\t\tsourcePath: resolved.sourcePath,\n\t\t\tmvrPlaceholder: resolved.mvrPlaceholder,\n\t\t\tcaptured: resolved.captured,\n\t\t},\n\t\t{\n\t\t\texcluded: opts.excludeFromCodegen ?? false,\n\t\t\t...(opts.mvrTypes !== undefined ? { mvrTypes: opts.mvrTypes } : {}),\n\t\t},\n\t);\n\t// The plugin contributes to the package-registry strategy under a\n\t// fixed key — the substrate orchestrator wires all packages'\n\t// contributions into the same per-stack registry.\n\tconst projection: PackageRegistryProjectionContribution = {\n\t\tkind: 'local',\n\t\tname,\n\t\tpackageId: resolved.packageId,\n\t\tupgradeCapId: resolved.upgradeCapId ?? null,\n\t\tmvrPlaceholder: resolved.mvrPlaceholder,\n\t\tsourcePath: resolved.sourcePath,\n\t};\n\tconst registryContribution: StrategyContributorDecl<\n\t\ttypeof PACKAGE_REGISTRY_CAPABILITY_KEY,\n\t\tPackageRegistryProjectionContribution\n\t> = {\n\t\tkind: 'strategy-contributor',\n\t\tcapabilityKey: PACKAGE_REGISTRY_CAPABILITY_KEY,\n\t\tstrategy: projection,\n\t\tautoMounted: true,\n\t};\n\treturn [snap, codegen, registryContribution, makePackageProjectionContribution(projection)];\n};\n\nconst makeKnownCapabilities = (\n\tname: string,\n\topts: KnownPackageOptions,\n\tresolved: KnownPackageResolved,\n): ReadonlyArray<Contribution> => {\n\tconst snap: SnapshotableDecl = makeSnapshotable(name, `known:${resolved.packageId}`);\n\tconst codegen: CodegenableDecl<'package'> = makeKnownCodegenable(\n\t\t{\n\t\t\tkind: 'known',\n\t\t\tname,\n\t\t\tpackageId: resolved.packageId,\n\t\t\tupgradeCapId: resolved.upgradeCapId ?? opts.upgradeCapId,\n\t\t\tmvrPlaceholder: resolved.mvrPlaceholder,\n\t\t},\n\t\topts.mvrTypes !== undefined ? { mvrTypes: opts.mvrTypes } : {},\n\t);\n\tconst projection: PackageRegistryProjectionContribution = {\n\t\tkind: 'known',\n\t\tname,\n\t\tpackageId: resolved.packageId,\n\t\tupgradeCapId: resolved.upgradeCapId ?? opts.upgradeCapId ?? null,\n\t\tmvrPlaceholder: resolved.mvrPlaceholder,\n\t\tsourcePath: null,\n\t};\n\tconst registryContribution: StrategyContributorDecl<\n\t\ttypeof PACKAGE_REGISTRY_CAPABILITY_KEY,\n\t\tPackageRegistryProjectionContribution\n\t> = {\n\t\tkind: 'strategy-contributor',\n\t\tcapabilityKey: PACKAGE_REGISTRY_CAPABILITY_KEY,\n\t\tstrategy: projection,\n\t\tautoMounted: true,\n\t};\n\treturn [snap, codegen, registryContribution, makePackageProjectionContribution(projection)];\n};\n\n/** Fold a fresh local-package publish output into the per-stack\n * `CoinRegistry`. Lifted VERBATIM from the orchestrator's former\n * `publishResultSink` (orchestrators/boot.ts): the same\n * `discoverCoinsFromPublish` walk + the same `CoinRecord` projection\n * (including the publisher-owns-cap gate on `treasuryCapId`).\n *\n * Re-homing this into the local `start` body — AFTER the publish output\n * is known, BEFORE `start` returns — preserves discovery timing: the\n * coin plugin `dependsOn` package, so it acquires only after package\n * readies, by which point the registry is already populated. The\n * previous decl-driven sink ran at the same point in the lifecycle\n * (post-`start` dispatch), so consumers see no ordering change. */\nexport const discoverPublishedCoins = (\n\tcoinRegistry: CoinRegistry,\n\tpackageName: string,\n\tpackageId: string,\n\toutput: LocalPackagePublishOutput,\n): Effect.Effect<void> =>\n\tEffect.gen(function* () {\n\t\tfor (const discovered of discoverCoinsFromPublish(output)) {\n\t\t\tconst record: CoinRecord = {\n\t\t\t\tkey: (discovered.symbol ?? discovered.witness).toLowerCase(),\n\t\t\t\ttype: discovered.fullCoinType,\n\t\t\t\twitness: discovered.witness,\n\t\t\t\tmoduleName: discovered.moduleName,\n\t\t\t\tdecimals: discovered.decimals ?? 0,\n\t\t\t\t...(discovered.symbol === undefined ? {} : { symbol: discovered.symbol }),\n\t\t\t\t...(discovered.displayName === undefined ? {} : { displayName: discovered.displayName }),\n\t\t\t\t...(discovered.iconUrl === undefined ? {} : { iconUrl: discovered.iconUrl }),\n\t\t\t\t...(!discovered.publisherOwnsCap || discovered.treasuryCapId === undefined\n\t\t\t\t\t? {}\n\t\t\t\t\t: { treasuryCapId: discovered.treasuryCapId }),\n\t\t\t\t...(discovered.metadataId === undefined ? {} : { metadataId: discovered.metadataId }),\n\t\t\t\tpackageId,\n\t\t\t\tpublishingPackageName: packageName,\n\t\t\t};\n\t\t\tyield* coinRegistry.register(record);\n\t\t}\n\t});\n\n// ---------------------------------------------------------------------------\n// Public factories\n// ---------------------------------------------------------------------------\n\n/** Build + publish a local Move package. The resolved value is\n * `LocalPackageResolved` so consumers that need bindings / source\n * path are typed correctly.\n *\n * Required `opts.publisher`: the account that signs the publish tx.\n * Pass the same `account('alice')` reference used elsewhere in the\n * stack — the package.s `dependsOn` includes `account/<publisher>`\n * so the substrate orders the publisher's keypair + funding strictly\n * before publish. */\nexport const localPackage = <\n\tName extends string,\n\tconst Publisher extends PublisherAccountMember,\n\tconst Capture extends PackageCapture | undefined = undefined,\n>(\n\tname: Name,\n\topts: LocalPackageOptions<Publisher, Capture>,\n) => buildLocalPlugin(name, opts);\n\n/** Verify-only against a fixed on-chain package id. The resolved\n * value is `KnownPackageResolved` — narrower than local, so the\n * bindings emitter rejects this at compose time. */\nexport const knownPackage = <Name extends string>(name: Name, opts: KnownPackageOptions) =>\n\tbuildKnownPlugin(name, opts);\n"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { keyedBucketSpec, liveBucketCodegen, staticBucketCodegen } from "../../c
|
|
|
2
2
|
//#region src/plugins/seal/codegen.ts
|
|
3
3
|
/** Build the seal instance's config-binding spec for `name`. `name` / `mode`
|
|
4
4
|
* are structural literals. For a `local-keygen` instance the object id / URL
|
|
5
|
-
* are dynamically-deployed (`
|
|
5
|
+
* are dynamically-deployed (`requireValue(dep, …)`) and `serverConfigs` is a runtime
|
|
6
6
|
* committee blob; for a `live` / `fork-known` instance these are DECLARED
|
|
7
7
|
* config, baked as literals. */
|
|
8
8
|
const sealBucketSpec = (structural) => {
|
|
@@ -71,14 +71,14 @@ const sealBucketSpec = (structural) => {
|
|
|
71
71
|
});
|
|
72
72
|
};
|
|
73
73
|
/** Build the LIVE Codegenable contribution for a seal instance. Bakes the
|
|
74
|
-
* resolved key-server fields + feeds the generic
|
|
74
|
+
* resolved key-server fields + feeds the generic deployment `values`
|
|
75
75
|
* channel. */
|
|
76
76
|
const makeSealCodegenable = (bindings) => liveBucketCodegen(sealBucketSpec({
|
|
77
77
|
name: bindings.name,
|
|
78
78
|
mode: bindings.mode
|
|
79
79
|
}), bindings);
|
|
80
80
|
/** Build the STATIC (stack-free) Codegenable contribution for a seal
|
|
81
|
-
* instance. Emits `
|
|
81
|
+
* instance. Emits `requireValue(dep, 'seal:<name>', '<key>')` for the runtime
|
|
82
82
|
* fields; the committed `seal.ts` carries no baked object id / endpoint URL. */
|
|
83
83
|
const makeSealStaticCodegen = (config) => staticBucketCodegen(sealBucketSpec(config));
|
|
84
84
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codegen.mjs","names":[],"sources":["../../../src/plugins/seal/codegen.ts"],"sourcesContent":["// Seal plugin — Codegenable contribution, via the UNIFIED config-binding\n// declaration.\n//\n// The seal plugin contributes ONE codegen shape — the `seal-key-server`\n// config the user-facing bindings consume to construct a `SealClient`.\n//\n// ONE declaration, TWO derivations (see `contracts/config-bindings.ts`). Every\n// seal instance folds into a single `generated/seal.ts` exporting\n// `export const seal = { <name>: SealBindings, ... }` (sibling-keyed bucket):\n// - LIVE (boot): bakes the resolved key-server object id / URL / configs\n// AND feeds the generic
|
|
1
|
+
{"version":3,"file":"codegen.mjs","names":[],"sources":["../../../src/plugins/seal/codegen.ts"],"sourcesContent":["// Seal plugin — Codegenable contribution, via the UNIFIED config-binding\n// declaration.\n//\n// The seal plugin contributes ONE codegen shape — the `seal-key-server`\n// config the user-facing bindings consume to construct a `SealClient`.\n//\n// ONE declaration, TWO derivations (see `contracts/config-bindings.ts`). Every\n// seal instance folds into a single `generated/seal.ts` exporting\n// `export const seal = { <name>: SealBindings, ... }` (sibling-keyed bucket):\n// - LIVE (boot): bakes the resolved key-server object id / URL / configs\n// AND feeds the generic deployment `values` channel.\n// - STATIC (committed tree): emits `requireValue(dep, 'seal:<name>', '<key>')`\n// so the committed `seal.ts` carries NO baked object id / endpoint URL.\n//\n// STRUCTURAL fields (`name`, `mode`) stay literals; the object id, key-server\n// URL, and `serverConfigs` committee (an array blob) are RUNTIME (loaded\n// config data), resolved at app build/dev time.\n\nimport type { CodegenableDecl } from '../../contracts/codegenable.ts';\nimport {\n\tkeyedBucketSpec,\n\tliveBucketCodegen,\n\tstaticBucketCodegen,\n\ttype BucketField,\n\ttype SiblingBucketSpec,\n} from '../../contracts/config-bindings.ts';\nimport type { JsonValue } from '../../orchestrators/codegen/deployment.ts';\nimport type { SealKeyServerEntry } from './registry-publish.ts';\n\n/** Codegen-emitted shape for seal. */\nexport interface SealBindings {\n\treadonly name: string;\n\treadonly objectId: string;\n\treadonly keyServerUrl: string;\n\treadonly serverConfigs: ReadonlyArray<SealKeyServerEntry>;\n\treadonly mode: 'local-keygen' | 'live' | 'fork-known';\n}\n\n/** User-declared known seal ids, available at factory time. The `live` and\n * `fork-known` modes resolve their `{objectId, keyServerUrl, serverConfigs}`\n * tuple at factory time (DECLARED config), so the committed `seal.ts` bakes\n * them as LITERALS. Absent for `local-keygen` (dev-deployed) whose key-server\n * ids/URL are dynamic. */\nexport interface SealKnownIds {\n\treadonly objectId: string;\n\treadonly keyServerUrl: string;\n\treadonly serverConfigs: ReadonlyArray<SealKeyServerEntry>;\n}\n\n/** Static-config shape a seal instance knows BEFORE acquire — the\n * structural names the stack-free `staticCodegen` hook needs. When `known`\n * is present (live / fork-known), its declared ids are baked as literals;\n * otherwise (local-keygen) every id resolves at app build/dev time. */\nexport interface SealStaticConfig {\n\treadonly name: string;\n\treadonly mode: SealBindings['mode'];\n\treadonly known?: SealKnownIds;\n}\n\ntype SealLiveState = SealBindings;\n\n/** Build the seal instance's config-binding spec for `name`. `name` / `mode`\n * are structural literals. For a `local-keygen` instance the object id / URL\n * are dynamically-deployed (`requireValue(dep, …)`) and `serverConfigs` is a runtime\n * committee blob; for a `live` / `fork-known` instance these are DECLARED\n * config, baked as literals. */\nconst sealBucketSpec = (structural: SealStaticConfig): SiblingBucketSpec<SealLiveState> => {\n\tconst known = structural.known;\n\tconst fields: ReadonlyArray<BucketField<SealLiveState>> =\n\t\tknown !== undefined\n\t\t\t? [\n\t\t\t\t\t{ key: 'name', variant: 'literal', value: structural.name },\n\t\t\t\t\t{ key: 'mode', variant: 'literal', value: structural.mode },\n\t\t\t\t\t{ key: 'objectId', variant: 'literal', value: known.objectId },\n\t\t\t\t\t{ key: 'keyServerUrl', variant: 'literal', value: known.keyServerUrl },\n\t\t\t\t\t{\n\t\t\t\t\t\tkey: 'serverConfigs',\n\t\t\t\t\t\tvariant: 'literal',\n\t\t\t\t\t\tvalue: known.serverConfigs as unknown as JsonValue,\n\t\t\t\t\t},\n\t\t\t\t]\n\t\t\t: [\n\t\t\t\t\t{ key: 'name', variant: 'literal', value: structural.name },\n\t\t\t\t\t{ key: 'mode', variant: 'literal', value: structural.mode },\n\t\t\t\t\t{ key: 'objectId', variant: 'resolved', tsType: 'string', live: (s) => s.objectId },\n\t\t\t\t\t{\n\t\t\t\t\t\tkey: 'keyServerUrl',\n\t\t\t\t\t\tvariant: 'resolved',\n\t\t\t\t\t\ttsType: 'string',\n\t\t\t\t\t\tlive: (s) => s.keyServerUrl,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tkey: 'serverConfigs',\n\t\t\t\t\t\tvariant: 'resolved',\n\t\t\t\t\t\t// Inline structural literal mirroring `SealKeyServerEntry` so the\n\t\t\t\t\t\t// committed `seal.ts` carries the concrete type (no emitted import).\n\t\t\t\t\t\ttsType:\n\t\t\t\t\t\t\t'ReadonlyArray<{ readonly objectId: string; readonly weight: number; readonly aggregatorUrl?: string }>',\n\t\t\t\t\t\tlive: (s) => s.serverConfigs as unknown as JsonValue,\n\t\t\t\t\t},\n\t\t\t\t];\n\treturn keyedBucketSpec({ bucket: 'seal.ts', kind: 'seal', key: structural.name, fields });\n};\n\n/** Build the LIVE Codegenable contribution for a seal instance. Bakes the\n * resolved key-server fields + feeds the generic deployment `values`\n * channel. */\nexport const makeSealCodegenable = (bindings: SealBindings): CodegenableDecl =>\n\tliveBucketCodegen(sealBucketSpec({ name: bindings.name, mode: bindings.mode }), bindings);\n\n/** Build the STATIC (stack-free) Codegenable contribution for a seal\n * instance. Emits `requireValue(dep, 'seal:<name>', '<key>')` for the runtime\n * fields; the committed `seal.ts` carries no baked object id / endpoint URL. */\nexport const makeSealStaticCodegen = (config: SealStaticConfig): CodegenableDecl =>\n\tstaticBucketCodegen(sealBucketSpec(config));\n"],"mappings":";;;;;;;AAkEA,MAAM,kBAAkB,eAAmE;CAC1F,MAAM,QAAQ,WAAW;CACzB,MAAM,SACL,UAAU,KAAA,IACP;EACA;GAAE,KAAK;GAAQ,SAAS;GAAW,OAAO,WAAW;EAAK;EAC1D;GAAE,KAAK;GAAQ,SAAS;GAAW,OAAO,WAAW;EAAK;EAC1D;GAAE,KAAK;GAAY,SAAS;GAAW,OAAO,MAAM;EAAS;EAC7D;GAAE,KAAK;GAAgB,SAAS;GAAW,OAAO,MAAM;EAAa;EACrE;GACC,KAAK;GACL,SAAS;GACT,OAAO,MAAM;EACd;CACD,IACC;EACA;GAAE,KAAK;GAAQ,SAAS;GAAW,OAAO,WAAW;EAAK;EAC1D;GAAE,KAAK;GAAQ,SAAS;GAAW,OAAO,WAAW;EAAK;EAC1D;GAAE,KAAK;GAAY,SAAS;GAAY,QAAQ;GAAU,OAAO,MAAM,EAAE;EAAS;EAClF;GACC,KAAK;GACL,SAAS;GACT,QAAQ;GACR,OAAO,MAAM,EAAE;EAChB;EACA;GACC,KAAK;GACL,SAAS;GAGT,QACC;GACD,OAAO,MAAM,EAAE;EAChB;CACD;CACH,OAAO,gBAAgB;EAAE,QAAQ;EAAW,MAAM;EAAQ,KAAK,WAAW;EAAM;CAAO,CAAC;AACzF;;;;AAKA,MAAa,uBAAuB,aACnC,kBAAkB,eAAe;CAAE,MAAM,SAAS;CAAM,MAAM,SAAS;AAAK,CAAC,GAAG,QAAQ;;;;AAKzF,MAAa,yBAAyB,WACrC,oBAAoB,eAAe,MAAM,CAAC"}
|