toilscript 0.1.37 → 0.1.39

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.
@@ -2877,11 +2877,31 @@ declare module "types:toilscript/src/dbcatalog" {
2877
2877
  * `schema_version`: a hash over the ORDERED field layout (name, type, is_array),
2878
2878
  * NOT the value-type name. Adding, removing, retyping, or REORDERING a field
2879
2879
  * changes it - so the runtime can tell a compatible (append-only) change from a
2880
- * breaking one, instead of silently misreading old rows. (Flat, like toildb's
2881
- * `SchemaDescriptor::layout_hash`: a change to a NESTED `@data` type's own fields
2882
- * does not bump the parent - that lands with recursive layouts later.)
2880
+ * breaking one, instead of silently misreading old rows.
2881
+ *
2882
+ * RECURSIVE into nested `@data` types: when a field's `typeName` is a KNOWN
2883
+ * `@data` type (a key of `typeMap`) and not already on the `seen` set (cycle
2884
+ * guard), the SAME running hash continues over that nested type's fields - so a
2885
+ * breaking change to a NESTED type bumps the OUTER `schema_version` and can be
2886
+ * `@migrate`d (instead of being refuse-only). This MUST stay byte-identical to
2887
+ * toildb's `SchemaDescriptor::layout_hash` (the runtime side): the algorithm,
2888
+ * the `seen` add/remove, and the declaration-order traversal are pinned in lock
2889
+ * step. A FLAT type (no field whose type is in `typeMap`) hashes to the SAME
2890
+ * value as the old flat hash, so existing pinned vectors stay green; an absent
2891
+ * `typeMap` (undefined) is flat/back-compatible.
2892
+ *
2893
+ * `typeMap` MUST contain the SAME set of `@data` types as the runtime's
2894
+ * `toildb.types` registry (collection value types + their nested types, EXCLUDING
2895
+ * old `*.migration.ts` shapes), or the two hashes diverge: a nested field whose
2896
+ * type is absent from the map on either side is treated as a LEAF on both sides.
2883
2897
  */
2884
- export function layoutHash(fields: FieldLayout[]): number;
2898
+ export function layoutHash(fields: FieldLayout[], typeMap?: Map<string, FieldLayout[]> | null, seen?: Set<string> | null): number;
2899
+ /** The recursion type map for `layoutHash`: every `@data` type the runtime's
2900
+ * `toildb.types` registry also contains (collection value types + their nested
2901
+ * types), EXCLUDING old `*.migration.ts` shapes (which the runtime registry
2902
+ * excludes by design). Both sides must recurse through the SAME set, so a
2903
+ * nested field whose type is NOT here is a leaf on both sides. */
2904
+ export function recursionTypeMap(sources: Source[]): Map<string, FieldLayout[]>;
2885
2905
  /** Extract the encoded field layout of a `@data` class, in declaration order,
2886
2906
  * mirroring `injectDataCodec` (skip static; `Array<T>` -> element + array flag;
2887
2907
  * else scalar/string/`Uint8Array`/nested-`@data` by its type name). */
@@ -2898,10 +2918,14 @@ declare module "types:toilscript/src/dbcatalog" {
2898
2918
  sourceInternalPath: string;
2899
2919
  }
2900
2920
  /** Every `@migrate` function across the (non-library) sources. `layouts` maps a
2901
- * `@data` class name to its field layout, for the old-version hash. A migration
2902
- * whose param/return is not a single named type, or whose old type has no
2903
- * layout, is skipped. */
2904
- export function collectMigrations(sources: Source[], layouts: Map<string, FieldLayout[]>): DataMigration[];
2921
+ * `@data` class name to its field layout, for the old-version hash. `typeMap`
2922
+ * (optional) is the recursion type map (see [`recursionTypeMap`]) so the old
2923
+ * version hashes RECURSIVELY through its nested `@data` fields - matching the
2924
+ * `schema_version` that old layout was deployed under (or the migratable old
2925
+ * version would never match a deployed recursive hash). Absent = flat. A
2926
+ * migration whose param/return is not a single named type, or whose old type
2927
+ * has no layout, is skipped. */
2928
+ export function collectMigrations(sources: Source[], layouts: Map<string, FieldLayout[]>, typeMap?: Map<string, FieldLayout[]> | null): DataMigration[];
2905
2929
  /** A resolved chain that migrates a stored OLD value all the way to a target
2906
2930
  * type: decode `oldType`, then apply `steps` in order (each `@migrate`). For a
2907
2931
  * direct migration `steps` has one entry; a chain `V0 -> V1 -> V2` has two. */
@@ -2922,6 +2946,94 @@ declare module "types:toilscript/src/dbcatalog" {
2922
2946
  */
2923
2947
  export function buildToilDbCatalog(program: Program): Uint8Array | null;
2924
2948
  export function buildToilDbTypes(program: Program): Uint8Array | null;
2949
+ /** Build the `toildb.route_kinds` section bytes, or `null` when no route needs
2950
+ * an extra runtime DB-policy clamp. The edge already derives the default kind
2951
+ * from the trusted HTTP method. This section only carries the stricter source
2952
+ * signal that the method clamp cannot infer: mutating-method routes explicitly
2953
+ * declared `@query`.
2954
+ *
2955
+ * Wire format (LE):
2956
+ * u16 format_version = 1
2957
+ * u16 n_routes
2958
+ * per route:
2959
+ * u8 method (same values as runtime Methods / request envelope)
2960
+ * u8 function_kind (0 = Query)
2961
+ * str route_pattern (same normalized pattern emitted into __toilMatch)
2962
+ */
2963
+ export function buildToilDbRouteKinds(program: Program): Uint8Array | null;
2964
+ /** Build the `toilstream.catalog` section bytes, or `null` if the program
2965
+ * declares no `@stream` class. Per Part 5 (LE):
2966
+ *
2967
+ * u16 format_version = 1
2968
+ * u16 n_streams
2969
+ * per stream:
2970
+ * str name
2971
+ * str route
2972
+ * u8 hook_presence_bitmask (bit0 connect..bit3 disconnect)
2973
+ * u8 declared_scope (0 regional/L2, 1 continental/L3)
2974
+ * u8 message_mode (0 raw, 1 @data-typed)
2975
+ * u32 max_frame_bytes (0 = use plan default)
2976
+ * u32 ingress_ring_bytes (0 = host chooses)
2977
+ * u32 message_value_data_id (fnv1a(typeName); 0 when raw)
2978
+ * u32 message_schema_version (recursive layoutHash; 0 when raw)
2979
+ * u16 stream_index (0-based position in this array)
2980
+ */
2981
+ export function buildToilStreamCatalog(program: Program): Uint8Array | null;
2982
+ /** Build the `toildaemon.catalog` section bytes, or `null` if the program
2983
+ * declares no `@daemon` class. Per Part 5 (LE):
2984
+ *
2985
+ * u16 format_version = 1
2986
+ * u8 has_daemon
2987
+ * u16 n_scheduled
2988
+ * per task:
2989
+ * str name
2990
+ * u16 task_index
2991
+ * u8 schedule_kind (0 interval, 1 cron)
2992
+ * u64 interval_ms
2993
+ * u64 cron_minute_mask (bits 0..59)
2994
+ * u32 cron_hour_mask
2995
+ * u32 cron_dom_mask
2996
+ * u16 cron_month_mask
2997
+ * u8 cron_dow_mask
2998
+ * u8 overlap_policy (0 default)
2999
+ * u8 catchup_policy (0 default)
3000
+ * u64 gas_hint
3001
+ *
3002
+ * Parses each `@scheduled(spec)` argument; fires diagnostics 9010/9011 for a
3003
+ * missing/non-string arg or an unparseable spec.
3004
+ */
3005
+ export function buildToilDaemonCatalog(program: Program): Uint8Array | null;
3006
+ /** Build the `toil.surface` section bytes (always emitted per artifact). Per
3007
+ * Part 5 (LE):
3008
+ *
3009
+ * u16 format_version = 1
3010
+ * u8 target_mode (0 hot, 1 cold)
3011
+ * u8 reserved0 (0)
3012
+ * u32 surface_flags (bit0 rest..bit5 render)
3013
+ * u16 abi_version
3014
+ * str build_id
3015
+ * u32 fingerprint
3016
+ * u32 data_coherence_hash
3017
+ * u32 pair_coherence_hash
3018
+ *
3019
+ * `targetMode` "cold" -> 1; "hot" or null (legacy single artifact, treated as
3020
+ * hot per Part 5) -> 0. The two coherence hashes use the SAME `layoutHash` /
3021
+ * `recursionTypeMap` machinery as the toildb catalog, so a hot pass and a cold
3022
+ * pass over the same sources compute identical `data_coherence_hash` and
3023
+ * `pair_coherence_hash` independently (doc 02 AN-4). `build_id` is empty and
3024
+ * `abi_version` is 1 in this increment (the toiljs build-identity plumbing and
3025
+ * the export-name fingerprint component land with the codegen increment).
3026
+ *
3027
+ * Returns `null` (no section) for a bare AssemblyScript module compiled in
3028
+ * LEGACY mode (`targetMode == null`) that declares NO Toil surface at all
3029
+ * (`@rest`/`@stream`/`@daemon`/`@scheduled`/`@database`/`@data`), so an ordinary
3030
+ * AS compile stays byte-identical (the same gating philosophy as the existing
3031
+ * `toildb.catalog`, which is absent without `@database`). Part 5 / doc 02 AN-2
3032
+ * requires the section in every TOIL artifact (including a legacy single-artifact
3033
+ * toil build, which always carries a toil surface); a non-toil module is not a
3034
+ * toil artifact. An explicit `--targetMode hot|cold` always emits the section.
3035
+ */
3036
+ export function buildToilSurface(program: Program, targetMode: string | null): Uint8Array | null;
2925
3037
  }
2926
3038
  declare module "types:toilscript/src/parser" {
2927
3039
  /**
@@ -2958,6 +3070,10 @@ declare module "types:toilscript/src/parser" {
2958
3070
  dependees: Map<string, Dependee>;
2959
3071
  /** Normalized paths whose `@rest` runtime import has already been injected. */
2960
3072
  restImportedSources: Set<string>;
3073
+ /** Normalized paths whose `@stream` module-level registry + the single
3074
+ * `stream_dispatch` export have already been emitted (a project may declare
3075
+ * several `@stream` classes, but the export is emitted exactly once). */
3076
+ streamExportedSources: Set<string>;
2961
3077
  /** Monotonic id handed to each `@ratelimit` route so the edge can key one
2962
3078
  * shared limiter per route. Program-wide (one Parser per program), assigned
2963
3079
  * deterministically in route declaration order. */
@@ -3079,6 +3195,99 @@ declare module "types:toilscript/src/parser" {
3079
3195
  * return; plus a module-level self-registration into the runtime `Rest` router.
3080
3196
  */
3081
3197
  private injectRestController;
3198
+ /**
3199
+ * Synthesize the cold-artifact daemon entry for a `@daemon` class (spec 03
3200
+ * sections 5.2 / 5.6 / 5.7, Reconciliation Part 2 cold exports). Mirrors
3201
+ * `injectRestController`: it scans the class methods once (same source-order
3202
+ * walk the `toildaemon.catalog` builder uses, so `task_index` <-> dispatch
3203
+ * index stay in lockstep), synthesizes a `__tick(task)` dispatcher onto the
3204
+ * class, and emits the two canonical cold module-level exports:
3205
+ *
3206
+ * `daemon_start(): i32` - runs once at cold-box boot; instantiates the
3207
+ * `@daemon` class, holds the single box-lifetime
3208
+ * instance, runs the optional `onStart()`, and
3209
+ * returns 0 (negative = Part 3 error bridge).
3210
+ * `scheduled_tick(task_id: i32): i64` - dispatches `instance.__tick(task_id)`
3211
+ * by switching on the catalog `task_index`;
3212
+ * returns 0 (negative = Part 3 error bridge).
3213
+ *
3214
+ * Unlike `injectRestController`, the exports are self-contained (they do NOT
3215
+ * route through an external runtime `Daemon` registry import). The injected
3216
+ * `register(...)` in `injectRestController` is pruned when nothing reachable
3217
+ * references it, but a top-level EXPORT that referenced an unresolved runtime
3218
+ * import would be a hard compile error (TS6054), so the host-called exports
3219
+ * are synthesized as plain top-level `export function`s and keep the one
3220
+ * box-lifetime instance in a module-level singleton (doc 03 D1 / section 2:
3221
+ * per-domain state lives in instance fields for the box lifetime).
3222
+ *
3223
+ * Fires diagnostic 9012 for a `@scheduled` method with a non-empty parameter
3224
+ * list or a non-void return type, and the 9008 warning for a `@daemon` class
3225
+ * with zero `@scheduled` tasks (a daemon may legitimately run only `onStart`).
3226
+ */
3227
+ private injectDaemonHandler;
3228
+ /**
3229
+ * Synthesize the hot-artifact stream entry for a `@stream` class (spec 03
3230
+ * sections 5.1 / 5.4, Reconciliation Part 2 hot exports). Mirrors
3231
+ * `injectDaemonHandler`: it scans the class methods once (same source-order
3232
+ * walk the `toilstream.catalog` builder + `streamHookMask` use), classifies
3233
+ * each by lifecycle-hook kind (`@connect`/`@message`/`@close`/`@disconnect`),
3234
+ * synthesizes a `__streamDispatch(event_kind)` dispatcher onto the class, and
3235
+ * emits the canonical hot module-level export:
3236
+ *
3237
+ * `stream_dispatch(event_kind: i32, stream_id_lo: i32, stream_id_hi: i32): i64`
3238
+ * - the per-connection event entry, emitted EXACTLY ONCE per module. It
3239
+ * reconstructs the i64 stream id from the two i32 halves, selects the
3240
+ * active `@stream` class's dispatch thunk from a module-level registry
3241
+ * (one entry per `@stream` class, in `toilstream.catalog` `stream_index`
3242
+ * order), switches on `event_kind` (1 connect / 2 message / 3 close /
3243
+ * 4 disconnect, the FIXED Part 2 ABI values), and returns the hook's
3244
+ * packed-i64 result (0 = no output / accept; a negative value is the
3245
+ * Part 3 reject/error bridge, wired with the real ring/StreamOutbound
3246
+ * runtime in a later increment).
3247
+ *
3248
+ * Each `@stream` class keeps its own MODULE-SINGLETON instance (a resident
3249
+ * per-connection box): the dispatch thunk constructs it on first use and REUSES
3250
+ * it across every later event, so per-connection state in instance fields
3251
+ * persists for the connection lifetime (the ResetMode::None resident box of
3252
+ * `05`). The thunk-array + the single export mirror the spec's `Streams.register`
3253
+ * model, but SELF-CONTAINED (no external runtime import): like
3254
+ * `injectDaemonHandler`, a top-level export referencing an unresolved runtime
3255
+ * import would be a hard compile error (TS6054), so the registry + the export
3256
+ * are plain module-level code emitted once (guarded by `streamExportedSources`,
3257
+ * exactly as `injectRestController` guards its one-per-source import).
3258
+ *
3259
+ * The `event_kind` ids are exactly the `toilstream.catalog` hook bitmask bits
3260
+ * plus one (connect=1 <-> bit0, message=2 <-> bit1, close=3 <-> bit2,
3261
+ * disconnect=4 <-> bit3, matching `streamHookMask` in `dbcatalog.ts`), so the
3262
+ * dispatch and the catalog never schism. `event_kind = 5` (channel, F10) is a
3263
+ * later increment: the base AST carries no `@channel` kind and the catalog mask
3264
+ * is 4-bit, so this shim emits the four lifecycle arms only.
3265
+ *
3266
+ * Active-stream selection (which registry entry a connection routes to) is
3267
+ * owned by the host/ring runtime (spec 5.1: the `Streams` singleton resolves the
3268
+ * stream identity off the ring); this increment routes to the host-selected
3269
+ * index, defaulting to 0, so a single-`@stream` module dispatches exactly and a
3270
+ * multi-`@stream` module compiles to one well-formed export.
3271
+ *
3272
+ * Only hooks the class actually declares get a dispatch arm; an event for an
3273
+ * absent hook falls through to `return 0` (a no-op success per the contract,
3274
+ * never a crash). A hook that declares parameters (the typed `@message`
3275
+ * `@data` arg, or a `StreamInbound`/`StreamPacket` view) is given a no-op arm
3276
+ * here too: the `StreamInbound`/`StreamPacket`/`StreamOutbound` runtime + the
3277
+ * ingress-ring read are owned by toiljs (spec 5.4) and land in a later
3278
+ * increment, so this self-contained shim cannot synthesize those argument
3279
+ * values yet; calling a zero-arg hook directly is the part that compiles and
3280
+ * runs today (every gating/catalog fixture uses the zero-arg/void hook form).
3281
+ *
3282
+ * Fires the 9013 warning for a `@stream` class with zero lifecycle hooks (a
3283
+ * hookless stream can never receive traffic), mirroring the daemon 9008 warning
3284
+ * shape; gating already rejects a hook outside a `@stream`.
3285
+ */
3286
+ private injectStreamHandler;
3287
+ /** True if a function signature takes no parameters and returns `void` (the
3288
+ * required `@scheduled` handler shape, spec 03 section 3.5). A missing or
3289
+ * non-`void`-named return type, or any parameter, is false. */
3290
+ private isVoidNoArgSignature;
3082
3291
  /**
3083
3292
  * Bind a `@user` class to `AuthService.getUser()` typing. The lib declares
3084
3293
  * `getUser(): AuthUser | null`; here we inject a `@global` `AuthUser` that
@@ -3319,6 +3528,8 @@ declare module "types:toilscript/src/program" {
3319
3528
  instancesByName: Map<string, Element>;
3320
3529
  /** Function decorated with `@main` (toil module entry point), if any. */
3321
3530
  mainFunction: FunctionPrototype | null;
3531
+ /** Class decorated with `@daemon` (cold L4 entry), if any. At most one per project. */
3532
+ daemonClass: ClassPrototype | null;
3322
3533
  /** Classes wrapping basic types like `i32`. */
3323
3534
  wrapperClasses: Map<Type, Class>;
3324
3535
  /** Managed classes contained in the program, by id. */
@@ -3493,6 +3704,15 @@ declare module "types:toilscript/src/program" {
3493
3704
  getElementByDeclaration(declaration: DeclarationStatement): DeclaredElement | null;
3494
3705
  /** Initializes the program and its elements prior to compilation. */
3495
3706
  initialize(): void;
3707
+ /**
3708
+ * Enforces the project-wide rule that a compilation unit using `@stream` cannot also
3709
+ * declare `@service` or `@remote` anywhere (spec 03 section 4.4). The host loads one
3710
+ * `hot.wasm` whose surface is either a stream node or an RPC service node, never both,
3711
+ * so mixing them is a deploy-time ambiguity caught fail-closed at compile time. Reported
3712
+ * at the offending `@service`/`@remote` site. Skipped in cold mode (neither flag is
3713
+ * admitted there anyway).
3714
+ */
3715
+ private enforceStreamServiceExclusion;
3496
3716
  /** Processes overridden members by this class in a base class. */
3497
3717
  private processOverrides;
3498
3718
  /** Processes a single overridden member by this class in a base class. */
@@ -3651,7 +3871,15 @@ declare module "types:toilscript/src/program" {
3651
3871
  /** Is a `@collection` field within a `@database` class. */
3652
3872
  Collection = 524288,
3653
3873
  /** Is a `@query`/`@action`/`@job`/`@derive`/`@admin` function (ToilDB kind). */
3654
- DbFunction = 1048576
3874
+ DbFunction = 1048576,
3875
+ /** Is a `@stream` protocol-handler class (L2/L3, hot artifact). */
3876
+ Stream = 2097152,
3877
+ /** Is a `@daemon` L4 always-on entry class (cold artifact, at most one). */
3878
+ Daemon = 4194304,
3879
+ /** Is a `@scheduled(spec)` task method inside a `@daemon` class. */
3880
+ Scheduled = 8388608,
3881
+ /** Is a `@connect`/`@message`/`@close`/`@disconnect` stream lifecycle hook. */
3882
+ StreamHook = 16777216
3655
3883
  }
3656
3884
  export namespace DecoratorFlags {
3657
3885
  /** Translates a decorator kind to the respective decorator flag. */
@@ -6553,7 +6781,14 @@ declare module "types:toilscript/src/ast" {
6553
6781
  Job = 35,
6554
6782
  Derive = 36,
6555
6783
  Migrate = 37,
6556
- Admin = 38
6784
+ Admin = 38,
6785
+ Daemon = 39,// @daemon class decorator (L4 entry; at most one per project)
6786
+ Scheduled = 40,// @scheduled(spec) method decorator inside a @daemon class
6787
+ Stream = 41,// @stream class decorator (L2/L3 stream protocol handler)
6788
+ Connect = 42,// @connect method in a @stream class (lifecycle hook)
6789
+ Message = 43,// @message method in a @stream class (lifecycle hook)
6790
+ Close = 44,// @close method in a @stream class (lifecycle hook)
6791
+ Disconnect = 45
6557
6792
  }
6558
6793
  export namespace DecoratorKind {
6559
6794
  /** Returns the kind of the specified decorator name node. Defaults to {@link DecoratorKind.CUSTOM}. */
@@ -7886,7 +8121,21 @@ declare module "types:toilscript/src/diagnosticMessages.generated" {
7886
8121
  Multiple_consecutive_numeric_separators_are_not_permitted = 6189,
7887
8122
  This_expression_is_not_callable_because_it_is_a_get_accessor_Did_you_mean_to_use_it_without = 6234,
7888
8123
  _super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class = 17009,
7889
- _super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class = 17011
8124
+ _super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class = 17011,
8125
+ Decorator_0_is_not_valid_in_the_hot_request_artifact = 9000,
8126
+ Decorator_0_is_not_valid_in_the_cold_daemon_artifact = 9001,
8127
+ Only_one_daemon_class_is_allowed_per_project = 9002,
8128
+ A_project_using_stream_cannot_declare_service_or_remote = 9003,
8129
+ Scheduled_is_only_valid_inside_a_daemon_class = 9004,
8130
+ Stream_hook_0_is_only_valid_inside_a_stream_class = 9005,
8131
+ Duplicate_stream_hook_0 = 9006,
8132
+ Stream_class_0_declares_no_lifecycle_hooks = 9007,
8133
+ Daemon_class_0_declares_no_scheduled_tasks = 9008,
8134
+ Decorator_0_does_not_accept_arguments = 9009,
8135
+ Scheduled_requires_a_single_string_schedule_argument = 9010,
8136
+ Scheduled_spec_0_is_not_a_valid_interval_or_cron_expression = 9011,
8137
+ Scheduled_handler_0_must_take_no_arguments_and_return_void = 9012,
8138
+ Stream_scope_must_be_a_StreamScope_enum_member = 9013
7890
8139
  }
7891
8140
  /** Translates a diagnostic code to its respective string. */
7892
8141
  export function diagnosticCodeToString(code: DiagnosticCode): string;
@@ -9146,6 +9395,9 @@ declare module "types:toilscript/src/compiler" {
9146
9395
  constructor();
9147
9396
  /** WebAssembly target. Defaults to {@link Target.Wasm32}. */
9148
9397
  target: Target;
9398
+ /** Toil compile surface mode. null = legacy single-artifact build (all surfaces allowed,
9399
+ * matching pre-split behavior). "hot" = request + stream surface. "cold" = daemon surface. */
9400
+ targetMode: string | null;
9149
9401
  /** Runtime type. Defaults to Incremental GC. */
9150
9402
  runtime: Runtime;
9151
9403
  /** If true, indicates that debug information will be emitted by Binaryen. */
@@ -9778,6 +10030,8 @@ declare module "types:toilscript/src/index-wasm" {
9778
10030
  export function setExportStart(options: Options, exportStart: string | null): void;
9779
10031
  /** Sets the `noUnsafe` option. */
9780
10032
  export function setNoUnsafe(options: Options, noUnsafe: boolean): void;
10033
+ /** Sets the `targetMode` option ("hot", "cold", or null for legacy single-artifact). */
10034
+ export function setTargetMode(options: Options, targetMode: string | null): void;
9781
10035
  /** Sets the `lowMemoryLimit` option. */
9782
10036
  export function setLowMemoryLimit(options: Options, lowMemoryLimit: number): void;
9783
10037
  /** Sets the `exportRuntime` option. */