graphddb 0.7.8 → 0.7.10
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/dist/cdc/index.d.ts +3 -2
- package/dist/cdc/index.js +3 -2
- package/dist/chunk-3UD3XIF2.js +860 -0
- package/dist/{chunk-HFFIB77D.js → chunk-3ZU2VW3L.js} +2 -1189
- package/dist/{chunk-IA6MW2HP.js → chunk-AD6ZQTTE.js} +4 -2
- package/dist/chunk-DFUKGU2Q.js +1197 -0
- package/dist/{chunk-NZRCBEWS.js → chunk-EOJDN3SA.js} +302 -728
- package/dist/cli.js +389 -29
- package/dist/{from-change-w2Ih8fkm.d.ts → from-change-Ty95KA8C.d.ts} +1 -1
- package/dist/{index-Deugy2sa.d.ts → index-Dc7d8mWI.d.ts} +161 -6
- package/dist/index.d.ts +127 -115
- package/dist/index.js +196 -59
- package/dist/linter/index.d.ts +5 -4
- package/dist/{maintenance-view-adapter-BCbgKG5d.d.ts → maintenance-view-adapter-BAZ9uBGe.d.ts} +122 -1091
- package/dist/{registry-pAnFcc62.d.ts → registry-LWE54Sdc.d.ts} +1 -1
- package/dist/{relation-depth-C9t4s9bt.d.ts → relation-depth-BRS513Tq.d.ts} +1 -1
- package/dist/spec/index.d.ts +4 -3
- package/dist/spec/index.js +18 -3
- package/dist/testing/index.d.ts +2 -1
- package/dist/testing/index.js +3 -2
- package/dist/transform/index.d.ts +460 -1
- package/dist/transform/index.js +2084 -1
- package/dist/types-BQLzTEqh.d.ts +1207 -0
- package/docs/python-bridge.md +17 -1
- package/package.json +7 -1
package/dist/spec/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export { A as AnyModelContract, B as BuiltContracts, C as ContextOwnership, b as ContextOwnershipMap, c as ContractBoundaryViolation, d as ContractInputs, e as ContractMap, f as ContractN1Violation,
|
|
3
|
-
import '../registry-
|
|
1
|
+
export { L as CompiledFragment, N as CompiledMutationPlan, O as DerivedConditionCheck, X as DerivedEdgeWrite, Y as DerivedIdempotencyGuard, Z as DerivedMaintainOutbox, _ as DerivedMaintainWrite, $ as DerivedOutboxEvent, a0 as DerivedUniqueGuard, a1 as DerivedUpdate, a2 as EntityRefResolver, a3 as MAX_TRANSACT_COMPOSE_ITEMS, a4 as assertNoCrossFragmentMaintainCollision, a5 as compileFragment, a6 as compileMutationPlan, a7 as compileSingleFragmentPlan, a8 as resetMaintenanceGraphCache, a9 as resolveLifecycle, aa as resolveMaintainers } from '../maintenance-view-adapter-BAZ9uBGe.js';
|
|
2
|
+
export { A as AnyModelContract, B as BuiltContracts, C as ContextOwnership, b as ContextOwnershipMap, c as ContractBoundaryViolation, d as ContractInputs, e as ContractMap, f as ContractN1Violation, X as PREPARED_FORMAT_VERSION, Y as PreparedBindMap, g as PreparedBindSpec, a as PreparedPlanDocument, h as PreparedPlanSpec, i as PreparedReadRouteSpec, P as PreparedWriteOpSpec, t as assertBundleSerializable, u as assertContractBoundaries, v as assertContractN1Safe, w as assertJsonSerializable, x as assertSupportedCondition, y as buildBridgeBundle, z as buildContexts, D as buildContracts, E as buildManifest, F as buildOperations, Z as buildPreparedPlanDocument, G as buildQuerySpec, H as buildTransactionSpec, I as buildTransactions, _ as canonicalJson, J as canonicalizeExpressionSpec, K as collectContractBoundaryViolations, L as collectContractN1Violations, $ as compilePreparedPlan, a0 as entityFingerprint, R as operationsContainScpNodes, U as operationsSpecVersion, a1 as planFingerprint } from '../index-Dc7d8mWI.js';
|
|
3
|
+
import '../registry-LWE54Sdc.js';
|
|
4
|
+
export { B as BridgeBundle, f as CommandContractMethodSpec, g as CommandResolutionTarget, a as CommandSpec, h as ComposeSpec, i as CompositionPlanSpec, d as ConditionSpec, b as ContextSpec, j as ContractCardinality, k as ContractCommandResult, l as ContractInputArity, m as ContractKeySpec, n as ContractKind, o as ContractResolution, C as ContractSpec, p as EXPR_VERSION, q as ExecutionPlanSpec, r as ExpressionArrNode, s as ExpressionFloatNode, t as ExpressionIntNode, u as ExpressionNode, v as ExpressionObjNode, w as ExpressionOpNode, x as ExpressionOperator, y as ExpressionRefNode, z as ExpressionRefOptNode, A as ExpressionScalar, E as ExpressionSpec, F as FilterSpec, M as Manifest, D as ManifestEntity, G as ManifestField, H as ManifestFieldType, I as ManifestGsi, J as ManifestKey, K as ManifestRelation, L as ManifestTable, N as OperationSpec, O as OperationsDocument, P as ParamSpec, R as QueryContractMethodSpec, Q as QuerySpec, U as RangeConditionSpec, V as ReadOperationType, S as SPEC_VERSION, W as SPEC_VERSION_SCP, X as SPEC_VERSION_SUPPORTED, e as SpecVersion, Y as TransactionItemSpec, Z as TransactionItemType, T as TransactionSpec, _ as WhenSpec, $ as WriteOperationType } from '../types-BQLzTEqh.js';
|
|
4
5
|
import '@aws-sdk/client-dynamodb';
|
package/dist/spec/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
MAX_TRANSACT_COMPOSE_ITEMS,
|
|
3
3
|
PREPARED_FORMAT_VERSION,
|
|
4
|
-
SPEC_VERSION,
|
|
5
4
|
assertBundleSerializable,
|
|
6
5
|
assertContractBoundaries,
|
|
7
6
|
assertContractN1Safe,
|
|
@@ -29,13 +28,26 @@ import {
|
|
|
29
28
|
resetMaintenanceGraphCache,
|
|
30
29
|
resolveLifecycle,
|
|
31
30
|
resolveMaintainers
|
|
32
|
-
} from "../chunk-
|
|
33
|
-
import "../chunk-
|
|
31
|
+
} from "../chunk-EOJDN3SA.js";
|
|
32
|
+
import "../chunk-DFUKGU2Q.js";
|
|
33
|
+
import {
|
|
34
|
+
EXPR_VERSION,
|
|
35
|
+
SPEC_VERSION,
|
|
36
|
+
SPEC_VERSION_SCP,
|
|
37
|
+
SPEC_VERSION_SUPPORTED,
|
|
38
|
+
canonicalizeExpressionSpec,
|
|
39
|
+
operationsContainScpNodes,
|
|
40
|
+
operationsSpecVersion
|
|
41
|
+
} from "../chunk-3UD3XIF2.js";
|
|
42
|
+
import "../chunk-3ZU2VW3L.js";
|
|
34
43
|
import "../chunk-PDUVTYC5.js";
|
|
35
44
|
export {
|
|
45
|
+
EXPR_VERSION,
|
|
36
46
|
MAX_TRANSACT_COMPOSE_ITEMS,
|
|
37
47
|
PREPARED_FORMAT_VERSION,
|
|
38
48
|
SPEC_VERSION,
|
|
49
|
+
SPEC_VERSION_SCP,
|
|
50
|
+
SPEC_VERSION_SUPPORTED,
|
|
39
51
|
assertBundleSerializable,
|
|
40
52
|
assertContractBoundaries,
|
|
41
53
|
assertContractN1Safe,
|
|
@@ -52,6 +64,7 @@ export {
|
|
|
52
64
|
buildTransactionSpec,
|
|
53
65
|
buildTransactions,
|
|
54
66
|
canonicalJson,
|
|
67
|
+
canonicalizeExpressionSpec,
|
|
55
68
|
collectContractBoundaryViolations,
|
|
56
69
|
collectContractN1Violations,
|
|
57
70
|
compileFragment,
|
|
@@ -59,6 +72,8 @@ export {
|
|
|
59
72
|
compilePreparedPlan,
|
|
60
73
|
compileSingleFragmentPlan,
|
|
61
74
|
entityFingerprint,
|
|
75
|
+
operationsContainScpNodes,
|
|
76
|
+
operationsSpecVersion,
|
|
62
77
|
planFingerprint,
|
|
63
78
|
resetMaintenanceGraphCache,
|
|
64
79
|
resolveLifecycle,
|
package/dist/testing/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { n as Executor, D as DynamoDBOperation, o as ReadExecOptions, p as ExecutorResult, q as BatchGetExecInput, P as PutInput, W as WriteExecOptions, r as WriteResult, s as UpdateInput, t as DeleteInput, u as BatchWriteExecItem, v as BatchExecOptions, T as TransactWriteExecItem, M as ModelStatic, w as DDBModel, c as ChangeEvent } from '../maintenance-view-adapter-
|
|
1
|
+
import { n as Executor, D as DynamoDBOperation, o as ReadExecOptions, p as ExecutorResult, q as BatchGetExecInput, P as PutInput, W as WriteExecOptions, r as WriteResult, s as UpdateInput, t as DeleteInput, u as BatchWriteExecItem, v as BatchExecOptions, T as TransactWriteExecItem, M as ModelStatic, w as DDBModel, c as ChangeEvent } from '../maintenance-view-adapter-BAZ9uBGe.js';
|
|
2
2
|
import '@aws-sdk/client-dynamodb';
|
|
3
|
+
import '../types-BQLzTEqh.js';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* In-process physical store backing the GraphDDB Memory Test Adapter
|
package/dist/testing/index.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createCdcEmulator
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-AD6ZQTTE.js";
|
|
4
|
+
import "../chunk-DFUKGU2Q.js";
|
|
4
5
|
import {
|
|
5
6
|
ClientManager,
|
|
6
7
|
MetadataRegistry,
|
|
7
8
|
resolveModelClass
|
|
8
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-3ZU2VW3L.js";
|
|
9
10
|
import {
|
|
10
11
|
TableMapping
|
|
11
12
|
} from "../chunk-PDUVTYC5.js";
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
import { E as ExpressionSpec } from '../types-BQLzTEqh.js';
|
|
3
|
+
|
|
1
4
|
/**
|
|
2
5
|
* Compile-time hoist transform + no-runtime-capture build lint for
|
|
3
6
|
* `DDBModel.prepare` (issue #206, design #203 — phase 2 on top of the phase-1
|
|
@@ -213,4 +216,460 @@ interface PreparedAotOptions {
|
|
|
213
216
|
*/
|
|
214
217
|
declare function transformPreparedSourceAot(fileName: string, sourceText: string, options: PreparedAotOptions): PreparedAotFileResult;
|
|
215
218
|
|
|
216
|
-
|
|
219
|
+
/**
|
|
220
|
+
* SCP expression lowerer + Portability Guard (issue #262, Phase 3 S2;
|
|
221
|
+
* behavior-contracts `expression-ir.md` §3).
|
|
222
|
+
*
|
|
223
|
+
* Lowers a TypeScript expression AST node to the closed Expression IR v1
|
|
224
|
+
* vocabulary shipped by #261 (`src/spec/expression.ts` /
|
|
225
|
+
* `ExpressionSpec` in `src/spec/types.ts`). The authoring surface is TS; the
|
|
226
|
+
* compiler analyzes the AST and lowers it to the §3 closed table:
|
|
227
|
+
*
|
|
228
|
+
* literal / ref・refOpt / coalesce (`??`) / cond (`?:` in expression
|
|
229
|
+
* position) / add・sub・mul・div・mod・neg / concat (string `+`, template
|
|
230
|
+
* literals) / eq (`===`)・ne (`!==`)・lt・le・gt・ge / and (`&&`)・or
|
|
231
|
+
* (`||`)・not (`!`) in expression position / obj・arr literals / len
|
|
232
|
+
* (`.length` on arrays).
|
|
233
|
+
*
|
|
234
|
+
* ## Portability Guard — whitelist, never blacklist
|
|
235
|
+
*
|
|
236
|
+
* The pass dispatches on a **whitelist** of syntax kinds (the same lint
|
|
237
|
+
* discipline as `prepared-transform.ts`): anything outside the table is a
|
|
238
|
+
* compile error with the precise source position (`file:line:col`) and the
|
|
239
|
+
* offending construct's name — loose equality (`==` / `!=`), truthiness
|
|
240
|
+
* coercion, function calls (`Math.*`, methods, user functions), `new`,
|
|
241
|
+
* `Date`, bitwise operators, `typeof`, `instanceof`, assignment, `++`/`--`,
|
|
242
|
+
* regex literals, element access, spread, closures, `this`, tagged templates,
|
|
243
|
+
* optional chaining beyond `refOpt` property semantics, and template
|
|
244
|
+
* substitutions with non-string parts. Nothing unknown ever reaches the IR.
|
|
245
|
+
*
|
|
246
|
+
* ## Monomorphic typing (expression-ir.md §5; issue R7 design decision)
|
|
247
|
+
*
|
|
248
|
+
* The IR is monomorphic: TS's overloaded `+` is resolved **statically** to
|
|
249
|
+
* `add` (numeric) vs `concat` (string) via the `TypeChecker`; implicit
|
|
250
|
+
* `toString` (string + number) is a compile error, as is any operand whose
|
|
251
|
+
* static type is `any` / `unknown` / an unresolvable union (the guard never
|
|
252
|
+
* guesses). Numeric literals classify by their **token text**: a decimal
|
|
253
|
+
* point or exponent (`1.5`, `1e3`) means float, otherwise int (`1`, `0xff`);
|
|
254
|
+
* `1.0` lowers to the canonical `{float: 1}` wrapper, and an integer literal
|
|
255
|
+
* beyond ±2^53−1 lowers exactly from its token text to `{int:"…"}`.
|
|
256
|
+
*
|
|
257
|
+
* **R7 (int/float vs DynamoDB N / `@number`)**: TS (and graphddb's `@number`
|
|
258
|
+
* schema type, which surfaces DynamoDB's `N`) has a single `number` type that
|
|
259
|
+
* does not distinguish int from float. A `number`-typed reference therefore
|
|
260
|
+
* classifies as the numeric kind **`num`** (int-or-float, decided by the
|
|
261
|
+
* runtime value per §5 "DB 由来の値は列型が int/float を決める"): it may
|
|
262
|
+
* combine with either a known-int or a known-float operand, while a
|
|
263
|
+
* **statically provable** int×float mix (`1 + 1.5`) is a compile error. A
|
|
264
|
+
* kind mismatch that only the runtime value can reveal surfaces as a loud
|
|
265
|
+
* evaluation **Failure** in the S5/S6 evaluators (monomorphic operand
|
|
266
|
+
* checks), never as silent wrongness — exactly the R7 posture (mistakes are
|
|
267
|
+
* compile/runtime friction, not corrupted data). Authors force the float
|
|
268
|
+
* interpretation with an explicit float literal (`1.0`).
|
|
269
|
+
*
|
|
270
|
+
* Nullability is tracked from the checker: a possibly-null(/undefined)
|
|
271
|
+
* operand is only accepted where the IR gives it meaning — as the left side
|
|
272
|
+
* of `??`, compared against the `null` literal (`x === null`), as a `?.`
|
|
273
|
+
* chain result, or as an `obj`/`arr` construction value. Anywhere else it is
|
|
274
|
+
* a compile error (`refOpt` / `coalesce` are the escape hatches).
|
|
275
|
+
*
|
|
276
|
+
* ## References — the unified Input Port model (issue #264, Phase 3 S4)
|
|
277
|
+
*
|
|
278
|
+
* `$.field` — a property chain rooted at the **Input Port binding** — lowers
|
|
279
|
+
* to `{ref:["input","field"]}` and a `.map`/fan-out element chain to
|
|
280
|
+
* `{ref:["item","field"]}`. The scope names `input` / `item` are FIXED,
|
|
281
|
+
* mirroring the `{param}` / `{item.<field>}` template scopes the runtimes
|
|
282
|
+
* already render (behavior-contracts `runtime-boundary.md` §4.1 /
|
|
283
|
+
* `template-rendering.md`): one reference model behind three authoring
|
|
284
|
+
* proxies (`defineTransaction`'s `p.*`, `mutation`'s `$.*`,
|
|
285
|
+
* `prepare`'s `$.*` — see `src/define/transaction.ts` 「Input Port 統一」).
|
|
286
|
+
*
|
|
287
|
+
* **Symbol-based root resolution (S2/S3 audit hard requirement)**: a root
|
|
288
|
+
* identifier is recognized as an input/item root by its **`ts.Symbol`
|
|
289
|
+
* identity** — the checker-resolved binding must be the exact declaration
|
|
290
|
+
* the caller registered (`inputRootSymbols` / `itemRootSymbols`), never by
|
|
291
|
+
* identifier text. A local binding shadowing `$`/`p` (block-scoped `const`,
|
|
292
|
+
* a nested arrow parameter, an `import { $ } …`) resolves to its own symbol
|
|
293
|
+
* and is loud-rejected as a non-input root — a shadow can never be silently
|
|
294
|
+
* lowered as an input reference.
|
|
295
|
+
*
|
|
296
|
+
* **Declared-input gate (#264 AC / the #243 lesson)**: when the caller
|
|
297
|
+
* provides the declared Input Port surface (`inputFields` / `itemFields`,
|
|
298
|
+
* derived from the `param.*` descriptors — `src/define/param.ts`), a
|
|
299
|
+
* reference to an UNDECLARED field is a positioned compile error — an
|
|
300
|
+
* unbound reference must never leak to runtime.
|
|
301
|
+
*
|
|
302
|
+
* A chain containing `?.` lowers to `{refOpt:[…]}` (null-propagating over
|
|
303
|
+
* the whole path — the table's `a?.b` row), and every plain `.` link
|
|
304
|
+
* requires a checker-proven **non-null receiver** (§3: `a.b.c` 型上
|
|
305
|
+
* non-null — a possibly-null intermediate is a positioned compile error
|
|
306
|
+
* here, not a runtime NULL_REF). Any other identifier root is a loud
|
|
307
|
+
* compile error.
|
|
308
|
+
*
|
|
309
|
+
* `xs.length` lowers to `{len:[xs]}` **only when the checker proves the
|
|
310
|
+
* receiver is an array**; `.length` on a string is rejected (§8: v1 excludes
|
|
311
|
+
* string length — TS/Rust/Python unit mismatch), and on a plain object type
|
|
312
|
+
* it is an ordinary `ref` path segment.
|
|
313
|
+
*
|
|
314
|
+
* ## Guarantees
|
|
315
|
+
*
|
|
316
|
+
* Every produced expression is round-tripped through the S1 validator /
|
|
317
|
+
* canonicalizer (`canonicalizeExpressionSpec`) before being returned, so an
|
|
318
|
+
* emitted node is **by construction** in canonical §2.3/§2.4 form and inside
|
|
319
|
+
* the closed vocabulary (and satisfies behavior-contracts `assertPortable` —
|
|
320
|
+
* it is built from JSON scalars, arrays, and plain objects only).
|
|
321
|
+
*
|
|
322
|
+
* Zero runtime evaluation lives here (S5/S6/S7); this module is build-time
|
|
323
|
+
* only (`graphddb/transform` — it imports the `typescript` optional
|
|
324
|
+
* dependency, never the runtime entry, and no runtime module imports it).
|
|
325
|
+
*/
|
|
326
|
+
|
|
327
|
+
/** Diagnostic codes emitted by the expression lowerer / Portability Guard. */
|
|
328
|
+
type ExpressionLowerDiagnosticCode =
|
|
329
|
+
/** A construct outside the expression-ir.md §3 closed set (whitelist miss). */
|
|
330
|
+
'scp-closed-set'
|
|
331
|
+
/** A monomorphic-typing violation (§5): kind mismatch, truthiness,
|
|
332
|
+
* possibly-null operand, or an unresolvable (`any` / `unknown`) type. */
|
|
333
|
+
| 'scp-type'
|
|
334
|
+
/** An unlowerable reference: the root does not resolve (by SYMBOL identity)
|
|
335
|
+
* to the Input Port / fan-out element binding — including a shadowed
|
|
336
|
+
* placeholder — or it names an undeclared input field (issue #264). */
|
|
337
|
+
| 'scp-ref'
|
|
338
|
+
/** The expression text does not parse (text entry point only). */
|
|
339
|
+
| 'scp-syntax';
|
|
340
|
+
/** One lowering diagnostic, positioned in the original source. */
|
|
341
|
+
interface ExpressionLowerDiagnostic {
|
|
342
|
+
readonly code: ExpressionLowerDiagnosticCode;
|
|
343
|
+
readonly category: 'error';
|
|
344
|
+
/** Human message; always names the offending construct. */
|
|
345
|
+
readonly message: string;
|
|
346
|
+
/** The offending construct's name (`'=='`, `'function call'`, …). */
|
|
347
|
+
readonly construct: string;
|
|
348
|
+
readonly file: string;
|
|
349
|
+
/** 1-based line in the source text. */
|
|
350
|
+
readonly line: number;
|
|
351
|
+
/** 1-based column in the source text. */
|
|
352
|
+
readonly column: number;
|
|
353
|
+
}
|
|
354
|
+
/** `file:line:col` + construct + message — the canonical one-line rendering
|
|
355
|
+
* (position info and the offending construct's name are always present). */
|
|
356
|
+
declare function formatExpressionLowerDiagnostic(d: ExpressionLowerDiagnostic): string;
|
|
357
|
+
/** Result of lowering one TS expression. */
|
|
358
|
+
interface ExpressionLowerResult {
|
|
359
|
+
/** The canonical `{ exprVersion: 1, expr }` envelope — present iff
|
|
360
|
+
* `errorCount === 0` (already validated by the S1 canonicalizer). */
|
|
361
|
+
readonly expression?: ExpressionSpec;
|
|
362
|
+
readonly diagnostics: readonly ExpressionLowerDiagnostic[];
|
|
363
|
+
readonly errorCount: number;
|
|
364
|
+
}
|
|
365
|
+
/** Thrown by {@link lowerExpressionTextOrThrow} on any guard violation. */
|
|
366
|
+
declare class ExpressionLowerError extends Error {
|
|
367
|
+
readonly diagnostics: readonly ExpressionLowerDiagnostic[];
|
|
368
|
+
constructor(diagnostics: readonly ExpressionLowerDiagnostic[]);
|
|
369
|
+
}
|
|
370
|
+
interface LowerTsExpressionOptions {
|
|
371
|
+
/** The program's type checker (monomorphic `+` resolution, `.length`
|
|
372
|
+
* disambiguation, truthiness/nullability checks are type-driven — and,
|
|
373
|
+
* since #264, symbol-based input-root resolution). */
|
|
374
|
+
readonly checker: ts.TypeChecker;
|
|
375
|
+
/** The source file containing the expression (position reporting). */
|
|
376
|
+
readonly sourceFile: ts.SourceFile;
|
|
377
|
+
/** Reported file name; defaults to `sourceFile.fileName`. */
|
|
378
|
+
readonly fileName?: string;
|
|
379
|
+
/**
|
|
380
|
+
* The `ts.Symbol`(s) of the **Input Port binding** (the `$` / `p`
|
|
381
|
+
* declaration — e.g. the `defineScpTransaction` callback's params
|
|
382
|
+
* parameter). A chain whose root identifier RESOLVES to one of these
|
|
383
|
+
* symbols lowers to the fixed `input` scope (`$.a` → `{ref:["input","a"]}`,
|
|
384
|
+
* issue #264's model). Matching is by **symbol identity, never identifier
|
|
385
|
+
* text** (S2/S3 audit requirement): a local binding shadowing the
|
|
386
|
+
* placeholder resolves to its own symbol and is a loud `scp-ref` error.
|
|
387
|
+
*/
|
|
388
|
+
readonly inputRootSymbols: ReadonlySet<ts.Symbol>;
|
|
389
|
+
/**
|
|
390
|
+
* The `ts.Symbol`(s) of a **fan-out element** binding (issue #263, Phase 3
|
|
391
|
+
* S3): a chain rooted at one of these lowers to the fixed `item` scope
|
|
392
|
+
* (`$el.qty` → `{ref:["item","qty"]}`) — the Expression IR spelling of the
|
|
393
|
+
* existing `{item.<field>}` forEach template reference. Optional; defaults
|
|
394
|
+
* to empty. Symbol-identity matched, like {@link inputRootSymbols}.
|
|
395
|
+
*/
|
|
396
|
+
readonly itemRootSymbols?: ReadonlySet<ts.Symbol>;
|
|
397
|
+
/**
|
|
398
|
+
* The DECLARED Input Port field names (issue #264: derived from the
|
|
399
|
+
* transaction's `param.*` descriptors — the single namespace shared with
|
|
400
|
+
* the serialized `ParamSpec`). When present, an input-root reference whose
|
|
401
|
+
* first segment is not in the set is a positioned `scp-ref` **compile
|
|
402
|
+
* error** (#243: never a runtime unbound leak). Absent → the checker type
|
|
403
|
+
* of the binding is the only gate (an unknown field still fails as an
|
|
404
|
+
* unresolvable-type error under `strict`, just less precisely).
|
|
405
|
+
*/
|
|
406
|
+
readonly inputFields?: ReadonlySet<string>;
|
|
407
|
+
/** The declared fan-out element field names; same gate as
|
|
408
|
+
* {@link inputFields}, for the `item` scope. */
|
|
409
|
+
readonly itemFields?: ReadonlySet<string>;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Lower one TypeScript expression AST node to a canonical
|
|
413
|
+
* `{ exprVersion: 1, expr }` {@link ExpressionSpec}. Whitelist-dispatched
|
|
414
|
+
* (Portability Guard): any construct outside the expression-ir.md §3 closed
|
|
415
|
+
* set yields an error diagnostic carrying the source position and the
|
|
416
|
+
* construct's name, and no expression is returned. A returned expression has
|
|
417
|
+
* already passed the S1 validator/canonicalizer.
|
|
418
|
+
*/
|
|
419
|
+
declare function lowerTsExpression(expr: ts.Expression, options: LowerTsExpressionOptions): ExpressionLowerResult;
|
|
420
|
+
/**
|
|
421
|
+
* A declared-input descriptor as the authoring surface provides it (issue
|
|
422
|
+
* #264: the `param.*` placeholder / `ParamDescriptor` shape of
|
|
423
|
+
* `src/define/param.ts` — every `param.string()` / `param.number()` /
|
|
424
|
+
* `param.literal(…)` / `param.array({…})` value matches structurally). The
|
|
425
|
+
* lowerer derives the Input Port TYPING from it — `param.number()` → the R7
|
|
426
|
+
* `num` kind (`ParamKind` carries no int/float distinction, exactly like
|
|
427
|
+
* DynamoDB `N` / `@number`), `param.literal(…)` → the literal-union kinds,
|
|
428
|
+
* `param.array({…})` → `arr` (so `.length` lowers to `len`) — and the
|
|
429
|
+
* declared-field set for the undeclared-reference compile gate.
|
|
430
|
+
*/
|
|
431
|
+
interface InputParamDescriptor {
|
|
432
|
+
readonly kind: 'string' | 'number' | 'literal' | 'array';
|
|
433
|
+
/** For `literal` params, the allowed values. */
|
|
434
|
+
readonly literals?: readonly (string | number)[];
|
|
435
|
+
/** For `array` params, the per-element field descriptors. */
|
|
436
|
+
readonly element?: Readonly<Record<string, InputParamDescriptor>>;
|
|
437
|
+
}
|
|
438
|
+
/** The TypeScript type text an {@link InputParamDescriptor} types its input
|
|
439
|
+
* field with (the same texts the S3 structural pass derives from a statically
|
|
440
|
+
* read `param.*` map — one typing rule for both entries). */
|
|
441
|
+
declare function inputParamTypeText(d: InputParamDescriptor): string;
|
|
442
|
+
interface LowerExpressionTextOptions {
|
|
443
|
+
/** Declared input fields: name → TypeScript type text (e.g. `{ qty:
|
|
444
|
+
* 'number', tag: 'string | null', items: 'string[]' }`). These type the
|
|
445
|
+
* input proxy for monomorphic resolution. */
|
|
446
|
+
readonly inputs?: Readonly<Record<string, string>>;
|
|
447
|
+
/**
|
|
448
|
+
* Declared input fields as `param.*` DESCRIPTORS (issue #264): name →
|
|
449
|
+
* placeholder, e.g. `{ qty: param.number(), status: param.literal('a','b'),
|
|
450
|
+
* items: param.array({ id: param.string() }) }`. The Input Port typing is
|
|
451
|
+
* derived per {@link inputParamTypeText}; a field present in both `params`
|
|
452
|
+
* and `inputs` takes the explicit `inputs` type text (the escape hatch for
|
|
453
|
+
* nullable / structured types the descriptor vocabulary cannot spell).
|
|
454
|
+
*/
|
|
455
|
+
readonly params?: Readonly<Record<string, InputParamDescriptor>>;
|
|
456
|
+
/** The input-proxy identifier; defaults to `'$'`. */
|
|
457
|
+
readonly inputName?: string;
|
|
458
|
+
/**
|
|
459
|
+
* Declared **fan-out element** fields (issue #263, Phase 3 S3): name →
|
|
460
|
+
* TypeScript type text, typing the element proxy of a `.map` body. When
|
|
461
|
+
* present, references rooted at {@link itemName} lower to the fixed `item`
|
|
462
|
+
* scope (`$el.qty` → `{ref:["item","qty"]}`). Absent → plain S2 behavior.
|
|
463
|
+
*/
|
|
464
|
+
readonly itemInputs?: Readonly<Record<string, string>>;
|
|
465
|
+
/** The element-proxy identifier (only meaningful with {@link itemInputs});
|
|
466
|
+
* defaults to `'$el'`. */
|
|
467
|
+
readonly itemName?: string;
|
|
468
|
+
/** Reported file name for diagnostics; defaults to `'scp-expression.ts'`. */
|
|
469
|
+
readonly fileName?: string;
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Convenience / opt-in CLI entry: lower a TypeScript expression given as
|
|
473
|
+
* TEXT, typing the input proxy from `options.inputs`. Builds a minimal
|
|
474
|
+
* in-memory `ts.Program` (with the standard lib, so `string` / array types
|
|
475
|
+
* resolve) and delegates to {@link lowerTsExpression}. Diagnostic positions
|
|
476
|
+
* are `file:line:col` within the synthesized module (the input declaration
|
|
477
|
+
* comes first; the expression text follows on its own lines).
|
|
478
|
+
*/
|
|
479
|
+
declare function lowerExpressionText(exprText: string, options?: LowerExpressionTextOptions): ExpressionLowerResult;
|
|
480
|
+
/** {@link lowerExpressionText}, throwing {@link ExpressionLowerError} (with
|
|
481
|
+
* every `file:line:col`-positioned, construct-named diagnostic) on violation. */
|
|
482
|
+
declare function lowerExpressionTextOrThrow(exprText: string, options?: LowerExpressionTextOptions): ExpressionSpec;
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* SCP structural lowering — Guard / Conditional (Φ) / `.map` onto the existing
|
|
486
|
+
* guard + forEach seams (issue #263, Phase 3 S3; behavior-contracts
|
|
487
|
+
* `semantic-contract-programming.md` 「構造化制御構文」/「Map」/「Conditional と Φ」,
|
|
488
|
+
* `scp-graphddb-consistency.md` §4.1).
|
|
489
|
+
*
|
|
490
|
+
* ## Structure-vs-expression dispatch
|
|
491
|
+
*
|
|
492
|
+
* SCP introduces no dedicated vocabulary for control structure: TS native
|
|
493
|
+
* syntax is lowered, and the compiler dispatches **deterministically** on
|
|
494
|
+
* Component presence — a branch / body that contains a Component (here: a
|
|
495
|
+
* `tx.*` write declaration) is a STRUCTURED construct and lowers to a
|
|
496
|
+
* gate/Map node (here: the existing `guard` slot / `forEach` binding); a pure
|
|
497
|
+
* expression lowers to Expression IR via the S2 lowerer (#262). The dispatch
|
|
498
|
+
* runs **before** the S2 lowerer ever sees a node, so a Component-bearing
|
|
499
|
+
* branch can never leak into Expression IR — and any shape that is neither a
|
|
500
|
+
* recognizable structural form nor a pure expression is a **positioned loud
|
|
501
|
+
* reject** (never a silent path):
|
|
502
|
+
*
|
|
503
|
+
* - **Guard** — `cond && tx.put(Model, {…})` as a body statement → ONE item
|
|
504
|
+
* carrying `guard: <cond lowered by S2>`. Guard-false = item skip = the
|
|
505
|
+
* same semantics as the legacy `when`-false, converging on the scp-error.md
|
|
506
|
+
* Skip rules (未生成 Port の伝播); the legacy `WhenSpec` is untouched
|
|
507
|
+
* (issue R2: string-compare `when` vs typed guard semantics are never
|
|
508
|
+
* mixed — `guard` is a separate node).
|
|
509
|
+
* - **Conditional (Φ)** — `cond ? tx.put(A, {…}) : tx.put(B, {…})` as a body
|
|
510
|
+
* statement → TWO items, `guard: cond` and `guard: {not:[cond]}`. Both
|
|
511
|
+
* branches exist statically (SSA Φ: the DAG carries both; the guard picks
|
|
512
|
+
* the executed side). Mixed shapes (one branch not a write, `: null`,
|
|
513
|
+
* ternary chains) are loud rejects in v1 — write the guard form or two
|
|
514
|
+
* explicit guarded items.
|
|
515
|
+
* - **Map** — `p.items.map(($el) => tx.put(Model, {…}))` as a body statement
|
|
516
|
+
* → the EXISTING `tx.forEach` recorder call over the declared array param.
|
|
517
|
+
* `$el.<field>` element references flow through the untouched recorder →
|
|
518
|
+
* `{item.<field>}` templates, and inside a lowered guard condition they
|
|
519
|
+
* lower to `{ref:["item","<field>"]}` (the S2 `itemRoots` scope). The
|
|
520
|
+
* serialized spec is **byte-identical** to the hand-written `tx.forEach`
|
|
521
|
+
* form, so the five language runtimes (which already expand `forEach`)
|
|
522
|
+
* need zero changes.
|
|
523
|
+
* - **Guard-in-guard** (`a && (b && tx.put(…))`), guarded conditionals, and
|
|
524
|
+
* nested `.map` fan-out are **loud rejects in v1** (decided in issue #263:
|
|
525
|
+
* `&&`-composition of the conditions — `(a && b) && tx.put(…)` — is
|
|
526
|
+
* equivalent and keeps the seam single-level; note the left-associative
|
|
527
|
+
* parse of `a && b && tx.put(…)` IS that composed form).
|
|
528
|
+
*
|
|
529
|
+
* ## The authoring surface (design decision, issue #263 scope item)
|
|
530
|
+
*
|
|
531
|
+
* Native operators cannot be intercepted by the `defineTransaction` recorder
|
|
532
|
+
* (a Proxy sees property reads and coercions, not `&&` / `?:` / control
|
|
533
|
+
* flow — coercing a sentinel is exactly what its ledger loud-rejects). So the
|
|
534
|
+
* native-syntax body form is a **new, opt-in, source-transformed** entry —
|
|
535
|
+
* `defineScpTransaction(params, (tx, p) => { … })` (`src/define/transaction.ts`)
|
|
536
|
+
* — whose `p` proxy is **value-typed** (`p.qty: number`, `p.items: {…}[]`), so
|
|
537
|
+
* the native form typechecks as ordinary TS. This pass rewrites its body
|
|
538
|
+
* statements onto the untouched recorder vocabulary (`guard:` options,
|
|
539
|
+
* `tx.forEach`); at runtime `defineScpTransaction` simply delegates to
|
|
540
|
+
* `defineTransaction`, so:
|
|
541
|
+
*
|
|
542
|
+
* - the TRANSFORMED output is ordinary recorder authoring (nothing about
|
|
543
|
+
* `defineTransaction` changes, and the pass is idempotent);
|
|
544
|
+
* - the pass **stamps every call it compiles** with the lowered-body marker
|
|
545
|
+
* (`SCP_LOWERED_MARKER`, a third argument), and `defineScpTransaction`
|
|
546
|
+
* THROWS at definition time when the marker is absent. This is the
|
|
547
|
+
* mechanical no-silent-path closure: the recorder's coercion ledger never
|
|
548
|
+
* fires on `===` / `!==` (no coercion) or bare truthiness (ToBoolean has
|
|
549
|
+
* no Proxy trap), and its consumed-field check is token-level — a param
|
|
550
|
+
* consumed by a native condition is masked whenever the same field ALSO
|
|
551
|
+
* surfaces faithfully in another item — so without the marker an
|
|
552
|
+
* untransformed body could silently record a dropped or unguarded item.
|
|
553
|
+
* With it, an untransformed `defineScpTransaction` never records
|
|
554
|
+
* anything; the ledger / differential / consumed-field checks remain as
|
|
555
|
+
* defense-in-depth behind the marker.
|
|
556
|
+
*
|
|
557
|
+
* Like `transformPreparedSource` (#206), this is a source-to-source pass and
|
|
558
|
+
* a file with ANY violation is returned unrewritten (fail loudly, never emit
|
|
559
|
+
* a half-transformed file). Unlike #206 it needs the S2 **type-directed**
|
|
560
|
+
* lowerer for conditions; the condition types come from the statically read
|
|
561
|
+
* `param.*` declarations of the `defineScpTransaction` params map (the single
|
|
562
|
+
* source of truth for the tx's input surface), so the pass still never loads
|
|
563
|
+
* user modules.
|
|
564
|
+
*
|
|
565
|
+
* ## Symbol-based root verification (issue #264; S2/S3 audit requirement)
|
|
566
|
+
*
|
|
567
|
+
* A condition is lowered by SLICING its text into a synthesized module whose
|
|
568
|
+
* `declare const p / $el` bindings carry the descriptor-derived types — a
|
|
569
|
+
* re-synthesis that maps identifiers by NAME. To make that sound on real
|
|
570
|
+
* authoring files, the pass binds the file with a single-file `ts.Program`
|
|
571
|
+
* (binder only — `noResolve`/`noLib`, still no user-module loading) and
|
|
572
|
+
* verifies, BEFORE slicing, that every identifier whose text matches the
|
|
573
|
+
* params / element binding name actually RESOLVES (by `ts.Symbol` identity)
|
|
574
|
+
* to the `defineScpTransaction` callback's parameter declaration. A local
|
|
575
|
+
* binding shadowing `p`/the element (a nested callback parameter, an import
|
|
576
|
+
* of the same name) resolves to its own symbol and is a positioned loud
|
|
577
|
+
* reject — never silently re-typed as an input reference. The `.map` /
|
|
578
|
+
* `tx.forEach` source receiver (`p.<arrayParam>`) is symbol-verified the
|
|
579
|
+
* same way, and a fan-out element parameter named like `tx` / `p` is
|
|
580
|
+
* rejected outright (the re-synthesis namespace is name-keyed, so the
|
|
581
|
+
* collision itself is the error). The recorder (`tx`) probes stay textual:
|
|
582
|
+
* a false positive there is always a loud reject, never a silent lowering.
|
|
583
|
+
*
|
|
584
|
+
* ## Known boundaries (documented, intentional)
|
|
585
|
+
*
|
|
586
|
+
* - **`.map` is gated stricter than the recorder**: the receiver must be a
|
|
587
|
+
* declared `param.array` (`p.<name>`), so a `.map` over a non-param literal
|
|
588
|
+
* array rejects at transform time even though an eager evaluation would be
|
|
589
|
+
* well-defined. Intentional: only fan-out over a declared array Port is a
|
|
590
|
+
* static Map node with structure-guaranteed termination
|
|
591
|
+
* (semantic-contract-programming.md Map — 配列 Port 限定), and the gated
|
|
592
|
+
* direction keeps every fan-out on the forEach seam the runtimes already
|
|
593
|
+
* expand.
|
|
594
|
+
* - **Φ records BOTH branches' write arguments at record time** (both writes
|
|
595
|
+
* exist statically in the DAG — SSA Φ — so the recorder evaluates both
|
|
596
|
+
* argument lists when the definition is captured). The Φ *condition* is
|
|
597
|
+
* S2-pure by dispatch, but the branch ARGUMENTS are ordinary recorder
|
|
598
|
+
* value positions: their soundness rests on the recorder's pre-existing
|
|
599
|
+
* differential-pass / coercion-ledger impurity detection, exactly as for
|
|
600
|
+
* any other write (an argument expression with side effects or per-pass
|
|
601
|
+
* divergence is rejected there, not here).
|
|
602
|
+
*
|
|
603
|
+
* Build-time only (`graphddb/transform`): imports the optional `typescript`
|
|
604
|
+
* dependency; no runtime module imports it (the `SCP_LOWERED_MARKER` import
|
|
605
|
+
* is a build-time constant read from the define layer, not a reverse edge).
|
|
606
|
+
*/
|
|
607
|
+
|
|
608
|
+
/**
|
|
609
|
+
* Diagnostic codes of the structural pass. The S2 expression codes pass
|
|
610
|
+
* through unchanged (a guard condition that violates the Portability Guard is
|
|
611
|
+
* reported at its position in the ORIGINAL file); the `scp-structural` /
|
|
612
|
+
* `scp-nesting` / `scp-map` / `scp-params` codes are the structural dispatch's
|
|
613
|
+
* own loud rejects.
|
|
614
|
+
*/
|
|
615
|
+
type StructuralLowerDiagnosticCode = ExpressionLowerDiagnosticCode
|
|
616
|
+
/** An undecidable structural shape, or a Component/write inside a pure
|
|
617
|
+
* expression position (the structure-vs-expression dispatch reject). */
|
|
618
|
+
| 'scp-structural'
|
|
619
|
+
/** Nested structural constructs — guard-in-guard, a guarded conditional, a
|
|
620
|
+
* ternary chain (v1 decision: loud reject; compose conditions with `&&`). */
|
|
621
|
+
| 'scp-nesting'
|
|
622
|
+
/** An unsupported `.map` fan-out shape (receiver not a declared array
|
|
623
|
+
* param, nested fan-out, unsupported callback shape). */
|
|
624
|
+
| 'scp-map'
|
|
625
|
+
/** The params map / callback is not statically readable, so a condition
|
|
626
|
+
* cannot be typed for the monomorphic S2 lowering (fail-closed). */
|
|
627
|
+
| 'scp-params';
|
|
628
|
+
/** One structural-lowering diagnostic, positioned in the original source. */
|
|
629
|
+
interface StructuralLowerDiagnostic {
|
|
630
|
+
readonly code: StructuralLowerDiagnosticCode;
|
|
631
|
+
readonly category: 'error';
|
|
632
|
+
readonly message: string;
|
|
633
|
+
/** The offending construct's name (`'&&'`, `'?:'`, `'.map'`, …). */
|
|
634
|
+
readonly construct: string;
|
|
635
|
+
readonly file: string;
|
|
636
|
+
/** 1-based line in the ORIGINAL source text. */
|
|
637
|
+
readonly line: number;
|
|
638
|
+
/** 1-based column in the ORIGINAL source text. */
|
|
639
|
+
readonly column: number;
|
|
640
|
+
}
|
|
641
|
+
/** Result of {@link transformScpTransactionSource} on one source file. */
|
|
642
|
+
interface ScpTransactionTransformResult {
|
|
643
|
+
readonly fileName: string;
|
|
644
|
+
/** The transformed source (identical to the input when nothing changed, in
|
|
645
|
+
* `check` mode, or when any violation was found). */
|
|
646
|
+
readonly text: string;
|
|
647
|
+
readonly changed: boolean;
|
|
648
|
+
/** Guard statements lowered to a `guard:` option (`cond && write`). */
|
|
649
|
+
readonly guardCount: number;
|
|
650
|
+
/** Conditional (Φ) statements expanded to two guarded items. */
|
|
651
|
+
readonly conditionalCount: number;
|
|
652
|
+
/** `.map` fan-out statements lowered to `tx.forEach`. */
|
|
653
|
+
readonly mapCount: number;
|
|
654
|
+
readonly diagnostics: readonly StructuralLowerDiagnostic[];
|
|
655
|
+
/** Count of error diagnostics (a build gate: non-zero fails, no rewrite). */
|
|
656
|
+
readonly errorCount: number;
|
|
657
|
+
}
|
|
658
|
+
interface ScpTransactionTransformOptions {
|
|
659
|
+
/** `transform` (default) verifies AND rewrites; `check` only verifies (the
|
|
660
|
+
* build-lint / drift gate) and never changes the text. */
|
|
661
|
+
readonly mode?: 'transform' | 'check';
|
|
662
|
+
}
|
|
663
|
+
/** `file:line:col — SCP structural lowering error [construct]: message`. */
|
|
664
|
+
declare function formatStructuralLowerDiagnostic(d: StructuralLowerDiagnostic): string;
|
|
665
|
+
/**
|
|
666
|
+
* Lower every `defineScpTransaction` body in one source file onto the
|
|
667
|
+
* existing recorder seams (see the module doc for the full dispatch table).
|
|
668
|
+
* A file carrying ANY violation is returned unrewritten with positioned
|
|
669
|
+
* diagnostics (fail loudly; never emit a half-transformed file). Idempotent:
|
|
670
|
+
* the transformed output contains only recorder vocabulary, which the pass
|
|
671
|
+
* leaves byte-identical.
|
|
672
|
+
*/
|
|
673
|
+
declare function transformScpTransactionSource(fileName: string, sourceText: string, options?: ScpTransactionTransformOptions): ScpTransactionTransformResult;
|
|
674
|
+
|
|
675
|
+
export { AOT_LOADER_LOCAL, AOT_PLANS_LOCAL, AOT_SHIM_EXPORT, type ExpressionLowerDiagnostic, type ExpressionLowerDiagnosticCode, ExpressionLowerError, type ExpressionLowerResult, HOIST_SLOT_PREFIX, type InputParamDescriptor, type LowerExpressionTextOptions, type LowerTsExpressionOptions, type PreparedAotFileResult, type PreparedAotOptions, type PreparedAotSite, type PreparedDiagnostic, type PreparedDiagnosticCode, type PreparedTransformOptions, type PreparedTransformResult, type ScpTransactionTransformOptions, type ScpTransactionTransformResult, type StructuralLowerDiagnostic, type StructuralLowerDiagnosticCode, formatExpressionLowerDiagnostic, formatStructuralLowerDiagnostic, inputParamTypeText, lintPreparedSource, lowerExpressionText, lowerExpressionTextOrThrow, lowerTsExpression, transformPreparedSource, transformPreparedSourceAot, transformScpTransactionSource };
|