/** * authoring.ts — native TS authoring surface(markers + leaf-schema 導出、reader 非依存)。 * * SCP の原則 C2「difference is catalog only」を authoring 層で成立させる COMMON 実装。consumer * (graphddb / litedbmodel / …)は **Catalog(leaf 専用コンポーネント)だけ**を供給し、Behavior の * 合成・命名・root 指定・配線・structured control は共有層が担う。本体の読み取り(`$` 参照・式・ * 構造化制御 → component-graph IR への lowering)は **AST リーダー**(`commands/ts-compile.ts` + * `commands/ts-extract.ts` + 規則 SSoT の `lowering.ts`)が行う。このモジュールは reader を持たず、 * 次のものだけを提供する: * * - **root / leaf マーカー**: `@behavior`(各 public static メソッド = 1 root Behavior)/ `@leaf` * (各 public static メソッド = 1 leaf)。どちらも runtime no-op — AST リーダーが名前で識別する。 * - **numeric Input Port 精度**: `Int`(i64)/ `Float`(f64)。裸の `number` は型抽出で fail-closed。 * - **authoring builder**: `opt`(`?.` = refOpt の source 表現・passthrough)/ `refsConnection` * (fanout の dedupe + implicit-source 剥がし)。式・構造化制御はネイティブ TS 構文(`+`/`?:`/ * `.map` 等)で書き、AST リーダーが expression/control IR へ 1:1 で lower する。 * - **leaf-schema 導出**: `@leaf` シグネチャから抽出した `LeafMeta`(`extractLeafMeta`)を * `CatalogEntry` へ射影する `catalogEntryFromLeaf` / `portSchemaFromPortable`。consumer は * catalog を手書きしない(§4.1)。 */ import type { CatalogEntry, PortSchema, PortableType } from "./behavior.js"; import type { BehaviorOptions, FanoutOptions } from "./lowering.js"; export { AuthoringFailure } from "./lowering.js"; export type { AuthoringFailureCode } from "./lowering.js"; /** * マーカーの適用位置(**dual-mode**): TC39 標準デコレータ `(value, context)`、legacy デコレータ * (`experimentalDecorators`)`(target, key, descriptor)`、素の呼び出し `behavior(fn)` のいずれでも * 型が通る。**両モードの型を持つのは必須**で、飾りではない: consumer のモデルクラスは自前の * 装飾 DSL(`@entity` / `@column` — legacy 形が多い)と同居し、モードはファイル単位で 1 つしか選べない。 * 標準形しか型を持たなければ legacy 側の consumer は authoring ファイルを `tsc --noEmit` に載せられない * (legacy のメソッドデコレータは戻り型 `void | TypedPropertyDescriptor<…>` を要求するため TS1270)。 * 実体は no-op(AST リーダーはマーカーを**宣言元**で識別する — 実行しない)。 */ type Marker = { (target: unknown, propertyKey: string | symbol, descriptor?: PropertyDescriptor): void; (target: T, context?: unknown): T; }; /** `@behavior` の型: マーカー本体(dual-mode)+ オプション形。**交差の左が先に解決される**ので * オプション形を左に置く(右に置くと `{onError}` が `(target:T):T` に食われて decorator にならない)。 */ type BehaviorMarker = { (opts: BehaviorOptions): Marker; } & Marker; /** * `@behavior` — root マーカー。`@behavior static` メソッド = 1 root Behavior(合成コンポーネント)。 * `@behavior({onError})` はそこに Error Policy の宣言を伴う形(マーカーとしては同じ no-op — AST * リーダーが宣言を**ソースから**読む)。 */ export declare const behavior: BehaviorMarker; /** * `@leaf` — leaf マーカー。`@leaf static` メソッド = 1 leaf(catalog エントリは AST が * シグネチャから導く — struct 設定なし)。 */ export declare const leaf: Marker; declare const bcIntBrand: unique symbol; declare const bcFloatBrand: unique symbol; /** Input Port を portable `int`(i64) として宣言する数値型(`$: { id: Int }`)。`number` に代入可能。 */ export type Int = number & { readonly [bcIntBrand]: "int"; }; /** Input Port を portable `float`(f64) として宣言する数値型(`$: { ratio: Float }`)。`number` に代入可能。 */ export type Float = number & { readonly [bcFloatBrand]: "float"; }; /** * `WireValue` — **不透明 wire 値**の Input Port 宣言型(portable `value`)。DB ドライバ境界のように * **本質的に generic** な束縛値(strict-typing-and-debox.md §D4b)を綴るための唯一の型で、`WireValue[]` * は heterogeneous な束縛値列(`{arr:"value"}` = `Vec` / `[]WireValue`)になる。名前は生成物 * 側の BC 所有 wire 型(`WireValue`/`WireRow`/`WireList`)と同一 — 宣言(TS)と生成コードで同じ語を使う。 * * これにより **全 op を単一の op-agnostic transport** で賄える(`@leaf static executeSQL(sql: string, * params: WireValue[], …)`)。行型・バインド形ごとに leaf を増やす(leaf zoo)と、1 回で済むはずの * typed↔汎用 de-box 境界が N 箇所へ散る — それを防ぐのがこの宣言型の役割。 * * **出力位置では「出力ワイヤ透過」の宣言**(bc#164): `@leaf` 戻り型 / 束縛注記(`const x: WireValue[] = …`) * が不透明ワイヤ形なら結果は de-box されずワイヤのまま流れ、下流の op-agnostic leaf が `typed→Value` の * 再 box 無しで消費する。**具体型を宣言した点だけが de-box 点**になる(=de-box は鎖全体で 1 回)。透過が * 許すのは「出力そのもの/出力配列の直下要素」だけで、record field や map value に埋もれた `WireValue` は * de-box 契約が無く lowering が LOUD に落とす(規則の SSoT は `setNodeOutType`・lowering.ts)。 * * **de-box 点の綴りは 2 つ・どちらも `tsc --strict` を通る**(宣言は普通の TypeScript である、が要件): * ```ts * // ① 終端 leaf が具体型を宣言する(呼び出し側に assertion が要らない・既定の綴り) * @leaf static materialize(rows: WireValue[]): UserRow[] { … } * const rows = Db.materialize(opaque); * // ② 束縛が具体型を宣言する(同じ汎用 leaf が呼び出し点ごとに別の行型を生むとき) * const rows: UserRow[] = Db.exec(sql, params) as UserRow[]; * ``` * ②の assertion は「不透明→具体」の**絞り込み**を TS に伝えるためのもの(`as unknown as` の二段は不要)。 * bc が読むのは**注記**であって cast ではないので、注記を落として cast だけにすると宣言(=戻り型 / 束縛) * と本体の導出型が食い違い、`OUTPUT_TYPE_MISMATCH` で loud に落ちる(黙って不透明のまま生成しない)。 * 透過は**ノード**の宣言なので `component.outputType` には現れない: 不透明のまま終わる鎖は * `BAD_TYPE_NOTATION` で fail-closed(呼び側に de-box 契約が無いため)。 * * 形は**メンバを持たない宣言型**(`{}` と同じ代入規則): 任意の wire 値・任意の行型をそのまま渡せる * (`Db.pluck(users, …)` — `users: UserRow[]` を `rows: WireValue[]` へ)。ブランドを持たせると TS の * weak-type 検査が `UserRow` を弾き、汎用境界に cast が必要になる。識別は名前一致ではなく **宣言元** * (このパッケージ内で宣言された `WireValue` か)で行う — `bcExportNameOf`(ts-compile.ts)と同じ規律。 */ export interface WireValue { } /** * `opt(x)` — optional-chain source マーカー。`opt(x).field` / `opt(x)` は AST リーダーが `refOpt` * (欠損許容参照)へ lower する。runtime は passthrough(実行されない・型のためだけの identity)。 */ export declare function opt(x: T): T; /** * `refsConnection(list, cb, opts)` — refs fanout の runtime SSoT。`list` の各要素へ `cb` を当て、 * `dedupeKey` で重複を落とし(`null`/`undefined` の dangling は drop)、`implicitSource` フィールドを * 剥がして `{ items, cursor }` を返す。AST リーダーは `.refsConnection` 呼びを fanout ノードへ lower し、 * この関数は ts-runtime 実行で同じ意味論を再現する。 */ export declare function refsConnection>(list: readonly E[], cb: (el: E) => R, opts: FanoutOptions): { items: R[]; cursor: string | null; }; /** * `LeafMeta` — `@leaf` シグネチャから `extractLeafMeta` が抽出する leaf の確定情報(runtime SSoT)。 * - `cardinality`: 型から導けない意味情報(one → item / many → items)。 * - `ports`: 入力 Port schema(各 Port の確定型を PortableType で宣言)。 * - `output`: 出力(`cardinality:"many"` のときは要素型)の確定型。 * - `async`: そのハンドラが async I/O か(#210・additive・省略時 sync)。宣言(`@leaf static async` / * `Promise` 戻り型)から `extractLeafMeta` が導く。**実行モードであって IR の形ではない**ので * 可搬 IR には載らず、catalog の宣言メタとして codegen(async/await を持つ言語の emitter)へ渡る。 */ export interface LeafMeta

= Record, R extends PortableType = PortableType, Card extends "one" | "many" = "one" | "many"> { cardinality: Card; ports: P; output: R; async?: boolean; } /** * `LeafDefinition` — leaf 1 件の宣言(name + {@link LeafMeta})。AST リーダーが `@leaf` シグネチャから * これを構築し `catalogEntryFromLeaf` に渡して CatalogEntry を導出する。**impl は載らない**: リーダーは * ソースを読むだけで本体を実行しないので、BC が leaf 実装を保持する経路は存在しない(実装は各言語の * transport 側にあり、生成モジュールが静的シンボルで直呼びする)。 */ export interface LeafDefinition

= Record, R extends PortableType = PortableType> { readonly name: string; readonly meta: LeafMeta; } /** * `portSchemaFromPortable` — PortableType を CatalogEntry の PortSchema へ射影する(scalar / opt / * arr / map / obj)。`required` は Port が省略可でない(`opt` ラップでない)ことを表す。 */ export declare function portSchemaFromPortable(pt: PortableType, required: boolean): PortSchema; /** * `catalogEntryFromLeaf` — leaf の runtime 注記から `CatalogEntry` を **導出**する(consumer は * catalog を手書きしない — §4.1)。 * - `inputPorts` = 各 Port の PortableType を PortSchema へ射影(scalar / opt / arr / map / obj)。 * - `output.shape` = cardinality(one → item / many → items)。 * - `elemType` = `output`(その leaf が返す要素の確定型。typed codegen / map 要素型の SSoT)。 * - `async` = `meta.async`(#210 宣言由来の I/O モデル注記。sync 宣言では省略 = 従来と完全に同一)。 * * `leafSymbol`(#176 op-agnostic transport 名)は leaf 宣言側では固定せず、native emitter が CLI * `--leaf-transport` override / 既定 `Leaf_` で解決する。 */ export declare function catalogEntryFromLeaf(def: LeafDefinition): CatalogEntry; //# sourceMappingURL=authoring.d.ts.map