@walkeros/core 4.1.0-next-1778668930820 → 4.1.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/CHANGELOG.md ADDED
@@ -0,0 +1,1089 @@
1
+ # @walkeros/core
2
+
3
+ ## 4.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - e155ff8: Cache reads through `checkCache` are now correct against async stores
8
+ (filesystem, Redis, any store with an async `get`). Previously a custom async
9
+ store could silently miss the cache.
10
+
11
+ `checkCache` returns a Promise. External callers must add `await`.
12
+
13
+ - e155ff8: Collector and destination buffers are now size-bounded with FIFO
14
+ drop-oldest eviction. Defaults: collector `queueMax: 1000`, destination
15
+ `queueMax: 1000`, destination `dlqMax: 100`. Set either knob to override per
16
+ scope. Drop counts surface in `collector.status.dropped` and
17
+ `collector.status.destinations[id]`.
18
+ - b276173: **Breaking:** `code: "<exportName>"` is no longer accepted on any
19
+ step. Replace with `import: "<exportName>"` alongside `package`.
20
+
21
+ **New:** Every step (source, transformer, destination, store) accepts
22
+ `import?: string`. With `package`, it selects a named export. `package` alone
23
+ still loads the default export. Inline code stays
24
+ `code: { push, type?, init? }`. Empty steps are valid no-ops. `flow_validate`
25
+ and the CLI bundler raise `OBSOLETE_CODE_STRING` on the legacy shape with a
26
+ precise rename hint.
27
+
28
+ - dd9f5ad: Pass-through transformer steps + closed-schema validation.
29
+
30
+ **Validation:** `validateTransformerEntry` in `@walkeros/core` is now the
31
+ single source of truth. Bundler, `flow_validate`, and collector runtime all
32
+ delegate. Closed schema: unknown top-level keys are errors. `code` + `package`
33
+ together is a `CONFLICT`.
34
+
35
+ **Pass-through steps:** A transformer entry with no `code` and no `package` is
36
+ valid; the collector synthesizes its push. Three variants:
37
+ - before/next chain only (named hop)
38
+ - cache only (e.g. dedup)
39
+ - mapping only (event-to-event transform via `Mapping.Config`)
40
+
41
+ **Mapping at the transformer position:** new `mapping?: Mapping.Config` field
42
+ on `Transformer.Config` / `InitTransformer`. Same shape as
43
+ `Destination.Config.mapping`, event-to-event semantic. `data` / `silent` are
44
+ ignored at the transformer position with a one-time warning.
45
+
46
+ **Engine tag:** synthesized instance now uses `type: 'pass'` (was `'path'`).
47
+ Hard cut.
48
+
49
+ **Runtime fixes:**
50
+ - `compileNext` handles mixed-shape `next` arrays (`["a", { case }]`) via a
51
+ new `'sequence'` variant.
52
+ - A destination's `before` referencing a pass-through transformer now walks
53
+ that transformer's own `before` / `next`.
54
+ - `cache.stop: true` at a pre-collector transformer halts the pipeline
55
+ (matches `cache.mdx`).
56
+
57
+ **Migration:** Typo keys on a step now fail validation.
58
+ `instance.type === 'path'` consumers must read `'pass'`. `runTransformerChain`
59
+ consumers should branch on the new `stopped` flag.
60
+
61
+ - adeebea: Route grammar: rename `case` to `one` (first-match dispatch) and add
62
+ `many` (all-match parallel fan-out, pre-collector only). `many` terminates the
63
+ main chain and is rejected at post-collector positions (`destination.before`,
64
+ `destination.next`); use multiple destinations for post-collector fan-out.
65
+ `RouteCaseConfig` is renamed to `RouteOneConfig`; no aliases.
66
+ - 13aaeaa: `Source.Context` no longer exposes `setIngest` or `setRespond`.
67
+ Server sources handling concurrent inbound requests must call
68
+ `context.withScope(rawScope, respond, body)` to bind per-request ingest and
69
+ respond. Browser and other single-scope sources keep working without changes.
70
+ - e800974: `Status.dropped` is now keyed by stepId, so operators can see at a
71
+ glance which step dropped events. Read with
72
+ `status.dropped["collector"]?.queue` or
73
+ `status.dropped["destination.<id>"]?.queue` / `.dlq`, or build the key with
74
+ the new `stepId()` helper exported from `@walkeros/core`. Breaking change: the
75
+ previous flat shape (`status.dropped.queue` / `.queuePush` / `.dlq`) and the
76
+ per-destination `dropped` field on `DestinationStatus` are removed.
77
+ - adeebea: Add `Flow.Store.cache` for store-level caching: read-through +
78
+ write-through wrapper with single-flight dedup, recursive composition via
79
+ `cache.store`, and per-wrapper counters. `CacheRule` is now a discriminated
80
+ union (`EventCacheRule | StoreCacheRule`); schema rejects inert fields in
81
+ store contexts.
82
+
83
+ Built-in `__cache` upgraded with LRU, `maxEntries: 10000`, batched eviction,
84
+ and active TTL sweep.
85
+
86
+ **Breaking:** `@walkeros/store-memory` is removed. Its logic is absorbed into
87
+ `__cache`. Migration: drop the store declaration, or omit `cache.store` to use
88
+ the built-in tier. `flow_validate` flags legacy references.
89
+
90
+ - 058f7ed: Add `validateJsonSchema` / `validateEventsJsonSchema` exports for
91
+ step-level validation config, promote the validate and no-`many` route schemas
92
+ to direct exports, and add optional `nodeType` / `subPath` cursor fields to
93
+ `IntelliSenseContext` for context-scoped autocomplete.
94
+ - 28a8ac2: Add step-level `validate?` primitive on every walkerOS step.
95
+ `validate:` is a declarative description of validation intent, like `cache` or
96
+ `consent`. Consumers decide how to enforce.
97
+
98
+ Restructure `Flow.ContractRule` to a uniform
99
+ `{ extends?, tagging?, description?, events?, schema? }` shape. A single
100
+ agnostic JSON Schema replaces the typed section fields (`globals`, `context`,
101
+ `custom`, `user`, `consent`); standard event field names live inside
102
+ `schema.properties.<name>`. `extends` resolves `schema` via additive
103
+ deep-merge.
104
+
105
+ Contracts are a description and governance concept: tooling, MCP, and humans
106
+ read them. Runtime enforcement is the consumer's call.
107
+
108
+ - fd6076e: Walker commands `destination`, `hook`, and `on` now take a single
109
+ Init object: `elb('walker destination', { code, config })`,
110
+ `elb('walker hook', { name, fn })`, `elb('walker on', { type, rules })`. The
111
+ previous positional forms and the `{ push }` shorthand are removed; the
112
+ `options` argument is gone from `collector.command`, `addDestination`, and
113
+ `commonHandleCommand`.
114
+
115
+ ### Patch Changes
116
+
117
+ - e800974: Fix `getByPath` silently returning undefined for objects created in a
118
+ different realm (Node `http.IncomingMessage`, `vm` contexts, worker threads,
119
+ iframes). The internal `instanceof Object` guard is replaced with a
120
+ cross-realm-safe check, so dot-notation paths now extract fields from native
121
+ request objects and other cross-realm sources.
122
+ - 1a8f2d7: Fix `resolveContracts` so a child contract that uses `extends`
123
+ inherits the parent's `tagging` when it does not redeclare it. Previously the
124
+ parent's `tagging` was silently dropped, which corrupted contract version
125
+ tracking for anyone building on a base contract.
126
+ - 1a8f2d7: Flow v4 routing & cache cleanup.
127
+
128
+ **Cache:**
129
+ - `cache.full` is renamed to `cache.stop`. Search-and-replace.
130
+ - `cacheRule.match` is now optional. Omitted means always-match. The literal
131
+ `'*'` is dropped from the schema and the TypeScript types; `compileMatcher`
132
+ still tolerates the string at runtime for migration.
133
+ - New `cache.namespace?: string` field. Omit to write keys directly to the
134
+ store. Same store + same key + same namespace = same cache entry.
135
+ - Implicit per-step namespace prefixes (`s:`, `t:`, `d:`) are removed. If you
136
+ relied on them to separate same-keyed caches across
137
+ sources/transformers/destinations using the same store, set
138
+ `cache.namespace` explicitly.
139
+
140
+ **Routing:**
141
+ - Unified recursive `Route` type. A Route is `string | Route[] | RouteConfig`.
142
+ - New `case` operator replaces the legacy `Route[]` first-match shape. The
143
+ legacy shape is compiled as an implicit `{ case: [...] }` for runtime
144
+ compatibility, but new configs should use `case` explicitly.
145
+ - `RouteConfig` is a disjoint union enforced at the TypeScript type level via
146
+ `never` fields: a single RouteConfig sets at most one of `next` / `case`. A
147
+ bare `{ match }` is a gate (pass-through when the match fires, fall-through
148
+ when it fails). JSON Schema validation currently emits `anyOf` and does not
149
+ enforce disjointness at runtime — see follow-up notes.
150
+ - Sequence sugar (`next: [A, B, C]`) is preserved.
151
+
152
+ **Path:**
153
+ - A transformer entry with no `code` is a `path` — a code-less passthrough.
154
+ The engine synthesizes `(e) => ({ event: e })`. Use paths to name and share
155
+ `before` chains across destinations. Validation: a path must declare at
156
+ least one of `package`, `before`, `next`, or `cache`.
157
+
158
+ **Schema & tooling:**
159
+ - Updated Zod schemas (cache, route, matcher).
160
+ - Updated MCP tool descriptions and resource references.
161
+ - Updated `flow_validate` to enforce the new constraints (`EMPTY_TRANSFORMER`
162
+ error code added).
163
+
164
+ **Migration:** Hard cut at the schema/type level. Configs using `cache.full`
165
+ will fail validation — rename to `stop`. Configs using `match: "*"` will fail
166
+ validation — omit `match`. Configs using `Route[]` first-match still work at
167
+ runtime (compiled as implicit `case`) but new configs should use `case`
168
+ explicitly.
169
+
170
+ `$schema: "v4"` is preserved. No version bump.
171
+
172
+ - c60ef35: Remove unused legacy fields `batchFn` and `batched` from
173
+ `Mapping.Rule`. Batch state lives on the destination via `BatchRegistry`,
174
+ never on mapping rules. No runtime impact.
175
+ - e800974: Internal pipeline failures in mapping, source startup, transformer
176
+ init, and destination init now log via the scoped logger and increment
177
+ `collector.status.failed`. Previously silent. User-supplied callbacks (mapping
178
+ `condition`/`fn`/`validate`, `on` subscriptions) log on throw but do not
179
+ affect `status.failed`. A source whose `init()` throws now stays
180
+ `config.init === false` instead of being marked initialized.
181
+ - e800974: Add typed accessors `Source.getSource`, `Destination.getDestination`,
182
+ `Transformer.getTransformer`, `Store.getStore`. Each takes a collector and a
183
+ step id and returns the registered instance with its declared generic
184
+ recovered, replacing the `Elb.Fn`-collapsed shape that the bag's index
185
+ signature exposes on read.
186
+
187
+ Callers (mainly tests and integrations that invoke a step's raw `push` through
188
+ the collector) no longer need `as any` / `as (rawData: X) => ...` casts at
189
+ this boundary. Each helper throws `<Kind> not found: <id>` for unknown ids. No
190
+ runtime behavior change.
191
+
192
+ ## 4.0.2
193
+
194
+ ### Patch Changes
195
+
196
+ - a6a0ea7: Rename routing types: `NextRule` to `Route`, `Next` to `RouteSpec`
197
+ (Zod schemas and `MatcherNext*` IDs renamed in step). Widen
198
+ `Flow.*.before/next` to `RouteSpec` so `Route[]` conditional routing
199
+ type-checks at the JSON layer. Fix the CLI bundler dropping `Route[]` data via
200
+ a narrowing cast on the inline path. Hard cut, no aliases; flow.json shape
201
+ unchanged.
202
+
203
+ ## 4.0.1
204
+
205
+ ### Patch Changes
206
+
207
+ - 381dfe7: Add an optional `setup` lifecycle to destinations, sources, and
208
+ stores.
209
+
210
+ Each package may now implement `setup?: SetupFn` to provision external
211
+ resources (BigQuery datasets and tables, Pub/Sub topics and subscriptions,
212
+ SQLite tables, webhook registrations, etc.). Setup is triggered only by the
213
+ new `walkeros setup <kind>.<name>` CLI command, never automatically by the
214
+ runtime, push, or deploy. Idempotency, ordering, and error semantics are the
215
+ package's responsibility; the framework provides the type slot, the CLI
216
+ invocation, and a `resolveSetup(value, defaults)` helper.
217
+
218
+ `LifecycleContext<C, E>` is the new shared context type used by both `setup`
219
+ and `destroy`. `DestroyContext` remains as a deprecated type alias for one
220
+ minor cycle. The `Types` bundle on `Destination`, `Source`, and `Store` gains
221
+ a 5th/6th/4th positional slot for setup options; existing aliases compile
222
+ unchanged because the slot defaults to `unknown`.
223
+ `Config<T>.setup?: boolean | SetupOptions<T>` is added across all three kinds
224
+ and validated by the corresponding Zod `ConfigSchema` plus the flow component
225
+ schemas in `@walkeros/core/schemas/flow.ts`.
226
+
227
+ CLI:
228
+ - `walkeros setup <kind>.<name>` runs a single component's `setup()` function.
229
+ - `<kind>` is `source`, `destination`, or `store` (transformers have no
230
+ provisioning).
231
+ - `--config <path>` (default `./flow.json`), `--flow <name>` for multi-flow
232
+ configs, plus standard `--json` / `--verbose` / `--silent`.
233
+ - Exit 0 on success or skip; non-zero on failure. Skip narration covers three
234
+ cases: no `setup()` on the package, `config.setup === false`, or
235
+ `config.setup` unset.
236
+ - When the package's `setup()` returns a non-undefined value, the CLI emits it
237
+ as JSON on stdout for `jq` piping.
238
+
239
+ - 1524275: Source lifecycle redesign: factory + eager `init` + collector-gated
240
+ `on()`
241
+
242
+ Source factories must now be side-effect-free. The collector calls
243
+ `Instance.init()` on each source eagerly after all factories register.
244
+ `require` no longer gates code execution. It gates `on(type)` delivery (events
245
+ queue in `Instance.queueOn` until the source is started, then replay).
246
+ `collector.pending.sources` has been removed; per-source state lives on
247
+ `Source.Instance` (`queueOn`) and `Source.Config` (`init`, `require`).
248
+
249
+ Migration: any source factory with side effects (queue draining, walker
250
+ command emission, listener attachment) should move those into the returned
251
+ Instance's optional `init` method. Tests asserting on
252
+ `collector.pending.sources` should read `collector.sources[id]` and inspect
253
+ `config.init` / `config.require` instead.
254
+
255
+ Fixes the elbLayer queue replay clobbering fresh consent/user state,
256
+ late-activated sources missing `walker run`, and inter-source require chains
257
+ racing when a non-required source's init fired a state-mutating walker command
258
+ before later require-gated sources had been registered.
259
+
260
+ - 03d7055: Merge `definitions` into `variables`. Single concept, single syntax
261
+ `$var.name(.deep.path)?`. Whole-string references preserve native type; inline
262
+ interpolation requires scalars. Deep paths and recursive resolution with cycle
263
+ detection now supported. `Flow.Definitions`, `Flow.Primitive`, and the `$def.`
264
+ reference syntax are removed.
265
+
266
+ ## 4.0.0
267
+
268
+ ### Major Changes
269
+
270
+ - 93ea9c4: Event model v4: breaking changes to the `Event`, `Source`, and
271
+ `Entity` shapes.
272
+ - `event.id` is now a W3C span_id (16 lowercase hex chars), generated by the
273
+ collector. Reference: W3C Trace Context (W3C Recommendation, January 2020).
274
+ - `event.version`, `event.group`, `event.count` are removed.
275
+ - `source.type` is now the source kind (e.g. `browser`, `gtag`, `mcp`, `cli`).
276
+ New `source.platform` holds the runtime (`web` | `server` | `app` | ...).
277
+ - `source.id` and `source.previous_id` are removed.
278
+ - Browser source now sets `source.url` and `source.referrer`.
279
+ - MCP source sets `source.tool` per emission. CLI source sets
280
+ `source.command`.
281
+ - `Entity.nested` and `Entity.context` are now optional. Root `event.nested`
282
+ and `event.context` remain required.
283
+ - Each source self-registers via TypeScript module augmentation of `SourceMap`
284
+ in `@walkeros/core`.
285
+ - App-side coordination (`/workspaces/developer/app`) is a follow-up plan, not
286
+ part of this release. Telemetry from v4 CLI/MCP will not validate against
287
+ the existing app schema until that follow-up ships.
288
+ - `Mapping.Rule.skip` is renamed to `Mapping.Rule.silent`. Customer flow.json
289
+ configs using `skip: true` in mapping rules must rename to `silent: true`.
290
+ Hard cut: no legacy alias, the field is gone.
291
+
292
+ - 942a7fe: Flow v4: type redesign and cross-flow references.
293
+
294
+ Breaking changes:
295
+ - Renamed `Flow.Settings` (single-flow shape) to `Flow`. The new
296
+ `Flow.Settings` is the arbitrary kv-bag inside `Flow.Config` (matches
297
+ `Destination.Settings` semantics).
298
+ - Renamed `Flow.Config` (root file shape) to `Flow.Json`.
299
+ - Removed `Flow.Web` and `Flow.Server`. Replaced by
300
+ `config.platform: 'web' | 'server'` (a string discriminator).
301
+ - Renamed `Flow.InlineCode` to `Flow.Code`.
302
+ - Renamed `Flow.SourceReference` / `DestinationReference` /
303
+ `TransformerReference` / `StoreReference` to `Flow.Source` / `Destination` /
304
+ `Transformer` / `Store` (Reference suffix dropped).
305
+ - Renamed `Flow.ContractEntry` to `Flow.ContractRule`.
306
+ - Lifted `bundle` and platform fields into the per-flow `config` block.
307
+ - `flow.json` `version` bumped from 3 to 4. v3 input is rejected (no compat
308
+ shim).
309
+
310
+ New:
311
+ - `$flow.X.Y` reference resolves to `flows.X.config.Y` in the same file.
312
+ Useful for linking a web flow's API destination to a server flow's deployed
313
+ URL without duplicating values.
314
+ - Per-flow `Flow.Config` block: `{ platform, url, settings, bundle }`.
315
+ - `walkeros validate` warns on unresolved `$flow.X.Y` (use `--strict` to
316
+ error). `walkeros bundle` and `walkeros deploy` always error on unresolved
317
+ refs.
318
+ - See `docs/migrating/v3-to-v4.mdx` on the website for the manual migration
319
+ steps. No automated codemod is shipped.
320
+
321
+ - cfc7469: **Breaking — `@walkeros/core`:** `fetchPackage(name, { baseUrl })`
322
+ now expects the host app to expose the v2 `/api/packages/[name]` endpoint that
323
+ returns the merged `WalkerOSPackage` shape directly (single round-trip,
324
+ `?expand=all`). The previous two-fetch pattern (`?path=package.json` +
325
+ `?path=dist/walkerOS.json`) is removed. Hosts must serve the v2 shape; the
326
+ offline jsdelivr fallback is unchanged.
327
+
328
+ **Feature — CLI/MCP/explorer:** Outbound walkerOS-aware HTTP clients now
329
+ identify themselves to the configured app origin via
330
+ `X-Walkeros-Client: walkeros-{cli|mcp}/{version}`. `@walkeros/explorer`
331
+ exports `setPackageTypesBaseUrl(url?)` so host apps can proxy `.d.ts` through
332
+ their own origin (used by the walkerOS Tag Manager app to drop the jsdelivr
333
+ CDN allowance entirely).
334
+
335
+ - 1ef33d9: **BREAKING:** Unified callback signatures across mapping and on.\*
336
+ subscriptions.
337
+
338
+ Every callback in walkerOS now reads `(data, context) => result`. Sources,
339
+ transformers, destinations, and stores already conformed; mapping and on.\*
340
+ join the family in v4.1.
341
+
342
+ ### Mapping callbacks
343
+
344
+ `fn`, `condition`, and `validate` now share a single shape:
345
+
346
+ `(value, context: Mapping.Context) => result`
347
+
348
+ `Mapping.Options` is removed. Replaced by `Mapping.Context`:
349
+
350
+ ```ts
351
+ interface Context {
352
+ event: WalkerOS.DeepPartialEvent;
353
+ mapping: Value | Rule;
354
+ collector: Collector.Instance; // required
355
+ logger: Logger.Instance; // required
356
+ consent?: WalkerOS.Consent; // resolved consent
357
+ }
358
+ ```
359
+
360
+ Rule-level `condition` is now `(event, context) => boolean`.
361
+ `Mapping.Options.props` is removed (no production callers).
362
+
363
+ #### Mapping upgrade
364
+
365
+ ```ts
366
+ // before
367
+ const fn: Mapping.Fn = (value, mapping, options) => /* … */;
368
+ const cond: Mapping.Condition = (value, mapping, collector) => /* … */;
369
+ const val: Mapping.Validate = (value) => /* … */;
370
+
371
+ // after
372
+ const fn: Mapping.Fn = (value, context) => /* … */;
373
+ const cond: Mapping.Condition = (value, context) => /* … */;
374
+ const val: Mapping.Validate = (value, context) => /* … */;
375
+ ```
376
+
377
+ In `$code:` strings (flow.json):
378
+
379
+ ```json
380
+ // before
381
+ "fn": "$code:(value, mapping, options) => …"
382
+ "condition": "$code:(value, mapping, collector) => …"
383
+
384
+ // after
385
+ "fn": "$code:(value, context) => …"
386
+ "condition": "$code:(value, context) => …"
387
+ ```
388
+
389
+ `context.mapping` replaces the second positional arg; `context.collector`,
390
+ `context.logger`, and `context.consent` are all available.
391
+
392
+ One-arg callbacks like `(value) => value.toUpperCase()` continue to work
393
+ unchanged.
394
+
395
+ ### On.\* subscription callbacks
396
+
397
+ `walker.on('consent', …)`, `walker.on('ready', …)`, etc. now receive
398
+ `(data, context: On.Context) => void | Promise<void>`. The legacy `Context`
399
+ interface, `*Config` aliases, and `Options` discriminated union are removed.
400
+
401
+ ```ts
402
+ interface Context {
403
+ collector: Collector.Instance; // required
404
+ logger: Logger.Instance; // required
405
+ }
406
+
407
+ type Fn<TData = unknown> = (
408
+ data: TData,
409
+ context: Context,
410
+ ) => void | Promise<void>;
411
+
412
+ type ConsentFn = Fn<WalkerOS.Consent>;
413
+ type SessionFn = Fn<Collector.SessionData | undefined>;
414
+ type UserFn = Fn<WalkerOS.User>;
415
+ type ReadyFn = Fn<void>;
416
+ type RunFn = Fn<void>;
417
+ type GenericFn = Fn<unknown>;
418
+ ```
419
+
420
+ The new `On.Subscription` alias is the registerable union for
421
+ `walker.on(action, X)`.
422
+
423
+ #### On.\* upgrade
424
+
425
+ ```ts
426
+ // before
427
+ walker.on('consent', { marketing: (collector, consent) => /* … */ });
428
+ walker.on('ready', (collector) => /* … */);
429
+ walker.on('session', (collector, session) => /* … */);
430
+
431
+ // after
432
+ walker.on('consent', { marketing: (consent, ctx) => /* … */ });
433
+ walker.on('ready', (_, ctx) => /* … */);
434
+ walker.on('session', (session, ctx) => /* … */);
435
+ ```
436
+
437
+ `ctx.collector` replaces the positional first arg; `ctx.logger` is also
438
+ available.
439
+
440
+ ### Why both at once
441
+
442
+ Both refactors follow the same `(data, context)` pattern. Shipping them in one
443
+ release means consumers do one search-and-replace pass instead of two, and the
444
+ codebase reaches full callback-signature consistency in v4.1.
445
+
446
+ ### Minor Changes
447
+
448
+ - 8e06b1f: **BREAKING:** Unified reference syntax: `$store:id` and
449
+ `$secret:NAME` now use the dot separator: `$store.id` and `$secret.NAME`.
450
+
451
+ The coherent rule across every walkerOS reference is:
452
+ - **`.`** key or path (resolver looks up or walks what follows)
453
+ - **`:`** literal value or raw-code payload (resolver uses what follows
454
+ verbatim)
455
+
456
+ `$var.`, `$def.`, `$env.NAME[:default]`, `$contract.`, and `$code:(…)` are
457
+ unchanged, they already fit the rule.
458
+
459
+ Every shipped example, published `walkerOS.json` metadata, doc page, and skill
460
+ has been updated. A new canonical reference-syntax guide lives at
461
+ `/docs/guides/reference-syntax`. Regex constants (`REF_VAR`, `REF_DEF`,
462
+ `REF_ENV`, `REF_CONTRACT`, `REF_STORE`, `REF_SECRET`, `REF_CODE_PREFIX`) are
463
+ exported from `@walkeros/core` import these instead of hand-rolling regexes.
464
+
465
+ ### Upgrade
466
+
467
+ Search-and-replace across your flow configs:
468
+
469
+ ```
470
+ $store:<id> → $store.<id>
471
+ $secret:<NAME> → $secret.<NAME>
472
+ ```
473
+
474
+ Everything else stays the same. Your `$var.*`, `$def.*`, `$env.*`,
475
+ `$contract.*`, and `$code:*` references need no changes.
476
+
477
+ ### Patch Changes
478
+
479
+ - 465775c: Add Monaco IntelliSense for `$flow.X` cross-flow references in
480
+ `Code`/`CodeBox`. Completion offers known sibling flow names from the parsed
481
+ flow document, hover describes the resolved target, decorations style matches
482
+ the other reference prefixes, and unknown flow names emit a warning marker.
483
+ Re-export `REF_FLOW` from `@walkeros/core` so consumers can build inline regex
484
+ tooling without reaching into the subpath.
485
+ - 3d50dd6: JSON Schema exports now include canonical `id` + `title` (e.g.
486
+ `Destination.Config`, `Logger.Config`) — replaces anonymous `__schema0` /
487
+ `object` / `any` labels. Extracts shared `LoggerConfigSchema` (was inlined
488
+ 5×). Removes deprecated `schemas/value-config.ts`. No TypeScript surface
489
+ changes.
490
+
491
+ ## 3.4.2
492
+
493
+ ## 3.4.1
494
+
495
+ ### Patch Changes
496
+
497
+ - 12adf24: Step examples can now carry a `title`, `description`, and `public`
498
+ flag. Non-public examples stay hidden from the docs and AI tools so first-time
499
+ visitors see only the canonical ones.
500
+ - 75aa26b: `useHooks` now isolates hook failures. A pre-hook that throws no
501
+ longer crashes the pipeline — the wrapped function is called directly and a
502
+ warning is logged. A post-hook that throws leaves the original result in
503
+ place. Added optional 4th `logger` parameter so warnings route through the
504
+ walkerOS Logger (falls back to `console.warn` when no logger is provided). All
505
+ collector call sites now pass `collector.logger`.
506
+
507
+ ## 3.4.0
508
+
509
+ ### Minor Changes
510
+
511
+ - 525f5d9: Introduce the standardized `StepExample.out` shape:
512
+ `[callable, ...args][]` where each tuple is a function call (first element is
513
+ the callable name) or a `['return', value]` tuple for transformer-style
514
+ returns. Every effect is self-describing; docs and tools can render it
515
+ uniformly without a per-package registry.
516
+
517
+ Ship the shared `formatOut` renderer from `@walkeros/core` for docs + app.
518
+ Also exports `StepEffect` and `StepOut` types. Migrate
519
+ `@walkeros/web-destination-gtag` to the new shape as the canary — its
520
+ multi-tool outputs (GA4 + Ads + GTM) now flatten into a single array of
521
+ `gtag(...)` and `dataLayer.push(...)` tuples in observed execution order.
522
+ Remaining destination packages ship the old shape until the bulk migration
523
+ (separate plan).
524
+
525
+ ### Patch Changes
526
+
527
+ - 74940cc: Add `TransformerSchemas` and `StoreSchemas` namespaces with
528
+ `ConfigSchema` / `configJsonSchema` exports. Mirrors the existing
529
+ `DestinationSchemas` / `SourceSchemas` pattern so every component type has a
530
+ documented Config schema available via `@walkeros/core/dev`.
531
+
532
+ Reconcile pre-existing drift between TS Config interfaces and their Zod
533
+ schemas:
534
+ - `DestinationSchemas.ConfigSchema` now includes `before`, `next`, `cache`,
535
+ `disabled`, `mock`, `include` (matching `Destination.Config`) and drops
536
+ phantom `onError` / `onLog` fields that were never wired in the TS type or
537
+ consumed at runtime.
538
+ - `SourceSchemas.ConfigSchema` now includes `disabled` and drops a phantom
539
+ `onError` field.
540
+ - `MappingSchemas.ConfigSchema` now includes `include`, matching
541
+ `Mapping.Config` (the base `Source.Config` extends).
542
+ - `CollectorSchemas.ConfigSchema` now includes `logger` and drops phantom
543
+ `verbose` / `onError` / `onLog` fields not present in `Collector.Config`.
544
+ - `CollectorSchemas.InitConfigSchema` now includes `transformers`, `stores`,
545
+ `hooks`, matching `Collector.InitConfig`.
546
+
547
+ Add a compile-time drift guard at
548
+ `packages/core/src/schemas/__tests__/config-drift.test-d.ts`. Any future
549
+ divergence between a Config TS interface and its Zod schema fails
550
+ `tsc --noEmit` (already wired into the project's `typecheck` script and CI).
551
+ Keys-only check; value types may still differ for recursive or generic-slot
552
+ fields where Zod cannot express TS-side precision.
553
+
554
+ ## 3.3.1
555
+
556
+ ## 3.3.0
557
+
558
+ ### Minor Changes
559
+
560
+ - 2849acb: **BREAKING CHANGE:** The `packages` block has moved from
561
+ `flow.<name>.packages` to `flow.<name>.bundle.packages`. Flow files using the
562
+ old shape fail fast with a migration error pointing to the new location.
563
+
564
+ Also adds `flow.<name>.bundle.overrides` — a `Record<string, string>` for
565
+ pinning transitive dependency versions, matching npm's `overrides` semantics.
566
+ Use this to resolve version conflicts when a transitive dependency's declared
567
+ range conflicts with another required version in the same tree (the original
568
+ motivating case: `@amplitude/engagement-browser` pins
569
+ `@amplitude/analytics-types@^1.0.0` while `@amplitude/analytics-browser`
570
+ transitively requires `analytics-types@2.11.1` exact — previously an
571
+ unresolvable bundler conflict).
572
+
573
+ **Migration:** move the existing `packages` block one level deeper into a new
574
+ `bundle` wrapper.
575
+
576
+ ```diff
577
+ {
578
+ "version": 3,
579
+ "flows": {
580
+ "default": {
581
+ "web": {},
582
+ - "packages": {
583
+ - "@walkeros/collector": {}
584
+ - },
585
+ + "bundle": {
586
+ + "packages": {
587
+ + "@walkeros/collector": {}
588
+ + }
589
+ + },
590
+ "sources": { },
591
+ "destinations": { }
592
+ }
593
+ }
594
+ }
595
+ ```
596
+
597
+ **Overrides example:**
598
+
599
+ ```json
600
+ {
601
+ "flows": {
602
+ "default": {
603
+ "web": {},
604
+ "bundle": {
605
+ "packages": {
606
+ "@walkeros/web-destination-amplitude": {}
607
+ },
608
+ "overrides": {
609
+ "@amplitude/analytics-types": "2.11.1"
610
+ }
611
+ }
612
+ }
613
+ }
614
+ }
615
+ ```
616
+
617
+ Overrides only substitute **transitive** dependencies during resolution —
618
+ direct package specs declared in `bundle.packages` always win. Overrides
619
+ targeting a direct local-path package emit a warning and are ignored. Peer
620
+ constraint mismatches against the chosen override emit a warning but do not
621
+ error (the override is an explicit user directive).
622
+
623
+ - 08c365a: Add `include` as a first-class field on `Destination.Config`
624
+ (destination-level) and `Mapping.Rule` (per-event override). The collector
625
+ resolves `include` in `processEventMapping` before calling `push()`,
626
+ flattening specified event sections into prefixed key-value pairs (e.g.
627
+ `data_price: 420`) and merging them as the bottom layer of `context.data`.
628
+
629
+ Rule-level `include` replaces config-level (not additive). Merge priority:
630
+ include (bottom) → config.data → rule.data (top, wins on conflict). The
631
+ `context` section correctly extracts `[0]` from OrderedProperties tuples.
632
+
633
+ New export: `flattenIncludeSections(event, sections)` from `@walkeros/core`.
634
+
635
+ - 08c365a: Add `skip?: boolean` to `Mapping.Rule` as a universal sibling of
636
+ `ignore`. Destinations can now honor a rule-level `skip` to process
637
+ `settings.*` side effects (identify, revenue, group, etc.) while omitting
638
+ their default forwarding call (`track()`, `capture()`, `event()`). Replaces
639
+ destination-specific `settings.skipTrack` / `settings.skipEvent` toggles.
640
+
641
+ `processEventMapping()` now returns an explicit `skip: boolean` field
642
+ alongside `ignore`. The collector does not short-circuit on `skip` — it still
643
+ calls `destination.push()` so the destination can run its side effects. The
644
+ destination implementation reads `context.rule?.skip` and gates its default
645
+ forwarding call on `!skip`.
646
+
647
+ `ignore: true` still wins when both flags are set on the same rule.
648
+
649
+ - 08c365a: Add `command` field to `Flow.StepExample` for routing non-event
650
+ inputs through walker commands (`consent`, `user`, `run`, `config`). Replaces
651
+ the gtag-only `_consent: true` magic marker pattern. Test runners can now
652
+ explicitly opt into `elb('walker <command>', in)` instead of pushing `in` as a
653
+ regular event.
654
+
655
+ **Breaking for anyone copying gtag's step-example test runner:** the
656
+ `_consent: true` magic marker on `mapping` is gone. Migrate to
657
+ `command: 'consent'` on `Flow.StepExample`.
658
+
659
+ ### Patch Changes
660
+
661
+ - 08c365a: Expand `getMarketingParameters` to recognise 25+ ad platform click
662
+ IDs (Pinterest, Reddit, Quora, Yandex, Outbrain, Taboola, Mailchimp, Klaviyo,
663
+ HubSpot, Adobe, Impact, CJ, Branch, plus Google's `wbraid`/`gbraid`). Add a
664
+ new `platform` field that resolves the click ID to a canonical platform
665
+ identifier (e.g. `gclid` → `google`, `fbclid` → `meta`). Multi-click-ID URLs
666
+ are resolved deterministically via a priority order.
667
+
668
+ Custom click-ID registries can be passed as the third argument to
669
+ `getMarketingParameters`, or via the new `clickIds` field in the session
670
+ source settings — so flow.json users can extend or override defaults without
671
+ touching code.
672
+
673
+ ## 3.2.0
674
+
675
+ ### Minor Changes
676
+
677
+ - eb865e1: Add chainPath to ingest metadata and support path-specific mocks via
678
+ --mock destination.ga4.before.redact='...'
679
+ - c0a53f9: Flow graph architecture: symmetric before/next hooks, mutable Ingest,
680
+ per-destination isolation.
681
+ - Add symmetric `before`/`next` to all step types (sources, transformers,
682
+ destinations)
683
+ - Add `Ingest` interface with mutable `_meta` tracking (hops, path)
684
+ - Parameterize `Transformer.Fn<T, E>` and `Result<E>` on event type
685
+ - Support `Result[]` return from transformers for fan-out
686
+ - Remove `Object.freeze(ingest)` — ingest is fully mutable
687
+ - Upgrade `setIngest` to create typed `Ingest` with `_meta`
688
+ - Clone ingest per destination to prevent cross-contamination
689
+ - Add `createMockContext` test utility for context construction
690
+
691
+ - f007c9f: Wire initConfig.hooks into collector instance. Simulation uses
692
+ prePush/postDestinationPush hooks for event capture. Hooks are wired by
693
+ startFlow before events fire.
694
+ - bf2dc5b: Add conditional routing and native cache as built-in config
695
+ properties on sources, transformers, and destinations.
696
+
697
+ **Routing:** NextRule[] in next/before properties enables conditional step
698
+ chaining, replacing @walkeros/transformer-router.
699
+
700
+ **Cache:**
701
+ - Cache rules use the same match syntax as routing (MatchExpression)
702
+ - Source cache: full pipeline caching with respond interception
703
+ - Transformer cache: step-level memoization, chain continues
704
+ - Destination cache: event deduplication
705
+ - Update rules modify cached results on read via getMappingValue
706
+ - Default per-collector memory store with namespaced keys
707
+
708
+ compileMatcher upgraded to use getByPath for scoped dot-paths (ingest.method,
709
+ event.name). Removed @walkeros/server-transformer-cache (replaced by native
710
+ cache).
711
+
712
+ - da0b640: Add include/exclude destination filter to collector.push PushOptions.
713
+ Sources can now control which destinations receive their events. Destination
714
+ simulation uses the full collector pipeline with include filter, giving
715
+ production-identical event enrichment, consent, and mapping.
716
+
717
+ ## 3.1.1
718
+
719
+ ## 3.1.0
720
+
721
+ ### Minor Changes
722
+
723
+ - 966342b: Add mergeConfigSchema to core and integrate into MCP package_get
724
+ tool.
725
+
726
+ package_get now returns schemas.config — a merged JSON Schema combining base
727
+ config fields (require, consent, logger, mapping, etc.) from core with the
728
+ package's typed settings schema. Runtime-only fields (env, onError, onLog) are
729
+ excluded.
730
+
731
+ - df990d4: Unified source simulation input. All source simulation uses
732
+ SourceInput { content, trigger?, env? } — one format for CLI, MCP, and tests.
733
+ Removes legacy runSourceLegacy and deprecated SimulateSource fields. CLI gains
734
+ --step flag. MCP flow_simulate drops example parameter (use flow_examples to
735
+ discover, then provide event). flow_examples now returns trigger metadata.
736
+ StepExample Zod schema aligned with TypeScript type.
737
+
738
+ ### Patch Changes
739
+
740
+ - dfc6738: MCP api tool: replace overloaded `id` param with explicit `projectId`
741
+ and `flowId`. CLI functions now throw structured ApiError with code and
742
+ details from the API response. mcpError forwards structured error data to MCP
743
+ clients.
744
+ - bee8ba7: Replace hardcoded package registry with live npm search. Package
745
+ catalog is now fetched dynamically from npm and enriched with walkerOS.json
746
+ metadata from CDN.
747
+
748
+ Change platform type from string to array. Packages declare platform as
749
+ ["web"], ["server"], or ["web", "server"]. Empty array means
750
+ platform-agnostic. The normalizePlatform utility handles backwards
751
+ compatibility with the old string format from already-published packages.
752
+
753
+ Remove outputSchema from package_get to prevent SDK validation crashes on
754
+ unexpected field values.
755
+
756
+ - 966342b: Add missing fields to Zod schemas: require, logger, ingest on
757
+ Source.Config and require, logger on Destination.Config. These fields existed
758
+ in TypeScript types but were absent from schemas, making them undiscoverable
759
+ via JSON Schema and MCP.
760
+
761
+ ## 3.0.2
762
+
763
+ ## 3.0.1
764
+
765
+ ## 3.0.0
766
+
767
+ ### Major Changes
768
+
769
+ - 0e5eede: BREAKING: Flow configs now require `"version": 3`. Versions 1 and 2
770
+ are no longer accepted. To migrate, change `"version": 1` or `"version": 2` to
771
+ `"version": 3` in your walkeros.config.json.
772
+ - d11f574: Rename Flow.Setup to Flow.Config and Flow.Config to Flow.Settings for
773
+ consistent Config/Settings naming convention at every level. Breaking change:
774
+ all type names, function names, schema names, and API URL paths (/configs →
775
+ /settings) updated.
776
+ - 23f218a: Replace flat/v2 contract format with named contracts supporting
777
+ extends inheritance.
778
+
779
+ BREAKING CHANGES:
780
+ - `contract` is now a map of named contract entries (e.g.,
781
+ `{ "default": { ... }, "web": { ... } }`)
782
+ - `version` field inside contracts removed
783
+ - `$tagging` renamed to `tagging`
784
+ - Legacy flat contract format removed
785
+ - `$globals`, `$context`, `$custom`, `$user`, `$consent` references removed
786
+ - Settings-level `contract` field removed (use named contracts at config
787
+ level)
788
+ - Auto-injection of `$tagging` into `collector.tagging` removed (use
789
+ `$contract.name.tagging` explicitly)
790
+ - Validator `contract` setting renamed to `events` (receives raw schemas, not
791
+ `{ schema: ... }` wrappers)
792
+
793
+ NEW FEATURES:
794
+ - Named contracts with `extends` for inheritance (additive merge)
795
+ - Generalized dot-path resolution: `$def.name.nested.path`,
796
+ `$contract.name.section`
797
+ - `$contract` as first-class reference type with path access
798
+ - `$def` inside contracts supported via two-pass resolution
799
+ - `$def` aliasing for reducing repetition: `{ "c": "$contract.web" }` then
800
+ `$def.c.events`
801
+
802
+ ### Minor Changes
803
+
804
+ - 6ae0ee3: Add v2 structured contract format with globals, context, custom,
805
+ user, and consent sections.
806
+
807
+ Contracts can now describe cross-event properties (globals, consent, etc.)
808
+ alongside entity-action event schemas. Top-level sections are JSON Schemas
809
+ that merge additively into per-event validation.
810
+
811
+ Breaking: None. Legacy flat contracts continue working unchanged. v2 is opt-in
812
+ via `version: 2` field.
813
+
814
+ - 1fe337a: Add hints field to walkerOS.json for lightweight AI-consumable
815
+ package context.
816
+
817
+ Packages can now export a `hints` record from `src/dev.ts` containing short
818
+ actionable tips with optional code snippets. Hints are serialized into
819
+ `walkerOS.json` by buildDev() and surfaced via the MCP `package_get` tool.
820
+
821
+ Pilot: BigQuery destination includes hints for authentication, table setup,
822
+ and querying.
823
+
824
+ - c83d909: Add Store types as fourth modular component type. Stores provide
825
+ pluggable key-value storage (get/set/delete/destroy) with sync and async
826
+ support for browser and server backends.
827
+ - b6c8fa8: Add stores as a first-class component type in Flow.Config. Stores get
828
+ their own `stores` section in flow settings, a `collector.stores` registry,
829
+ and `$store:storeId` env wiring in the bundler. Includes `storeMemoryInit` for
830
+ Flow.Config compatibility and type widening in cache/file transformers.
831
+
832
+ ### Patch Changes
833
+
834
+ - 2b259b6: Fix deterministic package version resolution in bundler.
835
+ - Two-phase resolve-then-install prevents version overwrites
836
+ - peerDependencies resolved at lowest priority (not equal to deps)
837
+ - Per-build temp directories prevent cross-build interference
838
+ - Optional peerDeps (peerDependenciesMeta) correctly skipped
839
+ - Prerelease versions handled with includePrerelease flag
840
+ - Package names validated against npm naming rules
841
+
842
+ - 2614014: Fix: `consent: {}` on destination config now auto-grants instead of
843
+ blocking all events forever
844
+ - 37299a9: Extract match logic (compileMatcher, MatchExpression, MatchCondition,
845
+ MatchOperator, CompiledMatcher) from router to core as shared utility. Router
846
+ now imports from core — no public API changes.
847
+ - 499e27a: Fix getByPath breaking on falsy intermediate values (0, false, "")
848
+ - d11f574: Fix $var/$def/$env resolution in transformer configs and env fields
849
+
850
+ Previously, `resolvePatterns` was not called on transformer configs or any
851
+ component's `env` field. This meant `$var.name`, `$def.name`, and `$env.NAME`
852
+ references in those positions were passed through as literal strings. Now all
853
+ component types (sources, destinations, transformers, stores) have both
854
+ `config` and `env` resolved consistently.
855
+
856
+ - 5cb84c1: Replace hand-written MCP resources with auto-generated JSON Schemas
857
+ from @walkeros/core. Add walkerOS.json to 5 transformer packages. Variables
858
+ resource remains hand-maintained (runtime interpolation patterns).
859
+ - 499e27a: Add sideEffects declarations to all packages for bundler tree-shaking
860
+ support.
861
+
862
+ ## 2.1.1
863
+
864
+ ### Patch Changes
865
+
866
+ - fab477d: Replace union transformer return type with unified
867
+ `Transformer.Result` object. Transformers now return `{ event }` instead of
868
+ naked events, and can optionally include `respond` (for wrapping) or `next`
869
+ (for branching). The `BranchResult` type and `__branch` discriminant are
870
+ removed.
871
+
872
+ ## 2.1.0
873
+
874
+ ### Minor Changes
875
+
876
+ - 7fc4cee: Add default values and improved descriptions to flow schemas for
877
+ better IDE IntelliSense
878
+ - cb2da05: Add data contracts for centralized event validation and documentation
879
+ - 2bbe8c8: Add destroy lifecycle method to all step types (sources,
880
+ destinations, transformers) and shutdown command to collector
881
+ - 3eb6416: Add unified `env.respond` capability. Any step (transformer,
882
+ destination) can now customize HTTP responses via
883
+ `env.respond({ body, status?, headers? })`. Sources configure the response
884
+ handler — Express source uses createRespond for idempotent first-call-wins
885
+ semantics. CLI serve mode removed (superseded by response-capable flows).
886
+ - 02a7958: Add WARN log level (ERROR=0, WARN=1, INFO=2, DEBUG=3). Logger
887
+ instances expose `warn()` method routed to `console.warn` and `json()` method
888
+ for structured output. Config accepts optional `jsonHandler`. MockLogger
889
+ includes both as jest mocks. CLI logger unified with core logger via
890
+ `createCLILogger()` factory.
891
+ - 026c412: Unified simulation API: single simulate() function replaces
892
+ simulateSource/simulateDestination/simulateTransformer/simulateFlow. Built-in
893
+ call tracking for destinations via wrapEnv. No bundling required for
894
+ simulation.
895
+ - 7d38d9d: Add `validateFlowSetup` for portable Flow.Setup validation with
896
+ line/column positions and IntelliSense context extraction.
897
+
898
+ ### Patch Changes
899
+
900
+ - 7fc4cee: Add contract as optional property to Flow.Setup schema
901
+ - 97df0b2: Step examples: upgrade all packages to blueprint pattern with inline
902
+ mapping, no intermediate variables, no `all` export
903
+ - 97df0b2: Step examples: add mapping field to StepExample type, rewrite Meta
904
+ Pixel examples with functional tests
905
+
906
+ ## 2.0.1
907
+
908
+ ### Patch Changes
909
+
910
+ - e34c11e: Align all packages to unified v2 with consistent dependency structure
911
+
912
+ ## 1.4.0
913
+
914
+ ### Minor Changes
915
+
916
+ - 7b2d750: Add walkerOS.json package convention for CDN-based schema discovery
917
+
918
+ ## 1.3.0
919
+
920
+ ### Minor Changes
921
+
922
+ - a4cc1ea: Add collector.status for per-source and per-destination delivery
923
+ tracking
924
+
925
+ ## 1.2.2
926
+
927
+ ### Patch Changes
928
+
929
+ - 7ad6cfb: Fix transformer chains computed on-demand instead of pre-computed
930
+
931
+ Transformer chains configured via `destination.before` now work correctly.
932
+ Previously, chains were pre-computed at initialization but the resolution
933
+ function was never called, causing `before` configuration to be silently
934
+ ignored.
935
+
936
+ **What changed:**
937
+ - Chains now compute at push time from `destination.config.before`
938
+ - Removed unused `collector.transformerChain` state
939
+ - Removed dead `resolveTransformerGraph()` function
940
+ - Dynamic destinations now support `before` property
941
+
942
+ ## 1.2.1
943
+
944
+ ### Patch Changes
945
+
946
+ - 6256c12: Add inline code support for sources, transformers, and destinations
947
+ - Add `InlineCodeSchema` with `push`, `type`, and `init` fields for embedding
948
+ JavaScript in flow configs
949
+ - Make `package` field optional in reference schemas (either `package` or
950
+ `code` required at runtime)
951
+ - Update `flow-complete.json` example with inline code demonstrations
952
+ including enricher transformer, debug destination, and conditional mappings
953
+
954
+ ## 1.2.0
955
+
956
+ ### Minor Changes
957
+
958
+ - f39d9fb: Add array support for transformer chain configuration
959
+
960
+ Enables explicit control over transformer chain order by accepting arrays for
961
+ `next` and `before` properties, bypassing automatic chain resolution.
962
+
963
+ **Array chain behavior:**
964
+
965
+ | Syntax | Behavior |
966
+ | -------------------------------- | ------------------------------------------------------ |
967
+ | `"next": "validate"` | Walks chain via each transformer's `next` property |
968
+ | `"next": ["validate", "enrich"]` | Uses exact order specified, ignores transformer `next` |
969
+
970
+ **Example:**
971
+
972
+ ```json
973
+ {
974
+ "sources": {
975
+ "http": {
976
+ "package": "@walkeros/server-source-express",
977
+ "next": ["validate", "enrich", "redact"]
978
+ }
979
+ },
980
+ "destinations": {
981
+ "analytics": {
982
+ "package": "@walkeros/server-destination-gcp",
983
+ "before": ["format", "anonymize"]
984
+ }
985
+ }
986
+ }
987
+ ```
988
+
989
+ When walking a chain encounters an array `next`, it appends all items and
990
+ stops (does not recursively resolve those transformers' `next` properties).
991
+
992
+ - 888bbdf: Add inline code syntax for sources, transformers, and destinations
993
+
994
+ Enables defining custom logic directly in flow.json using `code` objects
995
+ instead of requiring external packages. This is ideal for simple one-liner
996
+ transformations.
997
+
998
+ **Example:**
999
+
1000
+ ```json
1001
+ {
1002
+ "transformers": {
1003
+ "enrich": {
1004
+ "code": {
1005
+ "push": "$code:(event) => ({ ...event, data: { ...event.data, enriched: true } })"
1006
+ },
1007
+ "config": {}
1008
+ }
1009
+ }
1010
+ }
1011
+ ```
1012
+
1013
+ **Code object properties:**
1014
+ - `push` - The push function with `$code:` prefix (required)
1015
+ - `type` - Optional instance type identifier
1016
+ - `init` - Optional init function with `$code:` prefix
1017
+
1018
+ **Rules:**
1019
+ - Use `package` OR `code`, never both (CLI validates this)
1020
+ - `config` stays separate from `code`
1021
+ - `$code:` prefix outputs raw JavaScript at bundle time
1022
+
1023
+ ## 1.1.0
1024
+
1025
+ ### Minor Changes
1026
+
1027
+ - 20eca6e: Breaking change: Unified dynamic pattern syntax in Flow
1028
+ configuration, sorry!
1029
+
1030
+ **New syntax:**
1031
+ - `$def.name` - Reference definitions (replaces
1032
+ `{ "$ref": "#/definitions/name" }`)
1033
+ - `$var.name` - Reference variables (replaces `$variables.name`)
1034
+ - `$env.NAME` or `$env.NAME:default` - Reference environment variables
1035
+
1036
+ **Migration:**
1037
+
1038
+ | Old Syntax | New Syntax |
1039
+ | --------------------------------------- | -------------------------------------- |
1040
+ | `{ "$ref": "#/definitions/itemsLoop" }` | `$def.itemsLoop` |
1041
+ | `$variables.currency` | `$var.currency` |
1042
+ | `${GA4_ID}` or `${GA4_ID:default}` | `$env.GA4_ID` or `$env.GA4_ID:default` |
1043
+
1044
+ **Note:** Only `$env` supports defaults (`:default`) because environment
1045
+ variables are external and unpredictable. Variables (`$var`) are explicitly
1046
+ defined in config, so missing ones indicate a configuration error and will
1047
+ throw.
1048
+
1049
+ **Example:**
1050
+
1051
+ ```json
1052
+ {
1053
+ "variables": { "currency": "EUR" },
1054
+ "definitions": {
1055
+ "itemsLoop": { "loop": ["nested", { "map": { "item_id": "data.id" } }] }
1056
+ },
1057
+ "destinations": {
1058
+ "ga4": {
1059
+ "config": {
1060
+ "measurementId": "$env.GA4_ID:G-DEMO123",
1061
+ "currency": "$var.currency",
1062
+ "items": "$def.itemsLoop"
1063
+ }
1064
+ }
1065
+ }
1066
+ }
1067
+ ```
1068
+
1069
+ ### Patch Changes
1070
+
1071
+ - b65b773: Queue on() events until destination init completes
1072
+
1073
+ Destinations now receive `on('consent')` and other lifecycle events only after
1074
+ `init()` has completed. Previously, `on()` was called before `init()`,
1075
+ requiring workarounds like gtag's `initializeGtag()` call inside its `on()`
1076
+ handler.
1077
+
1078
+ Also renamed queue properties for clarity:
1079
+ - `destination.queue` → `destination.queuePush`
1080
+ - `destination.onQueue` → `destination.queueOn`
1081
+
1082
+ ## 1.0.0
1083
+
1084
+ ### Major Changes
1085
+
1086
+ - 67c9e1d: Hello World! walkerOS v1.0.0
1087
+
1088
+ Open-source event data collection. Collect event data for digital analytics in
1089
+ a unified and privacy-centric way.