@platforma-open/milaboratories.sort-seq-analysis.block 1.0.3 → 1.0.5

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/index.js CHANGED
@@ -1,26 +1,4 @@
1
- //#region \0rolldown/runtime.js
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
9
- var __copyProps = (to, from, except, desc) => {
10
- if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
- key = keys[i];
12
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
- get: ((k) => from[k]).bind(null, key),
14
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
- });
16
- }
17
- return to;
18
- };
19
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
20
- value: mod,
21
- enumerable: true
22
- }) : target, mod));
23
- //#endregion
1
+ import { r as __toESM, t as __commonJSMin } from "./rolldown-runtime-DC62tzP2.js";
24
2
  //#region ../model/dist/columns.js
25
3
  /** Annotation keys this block reads on upstream columns. */
26
4
  const Annotation$1 = {
@@ -36,6 +14,8 @@ const PColumnName$1 = {
36
14
  MutationCount: "pl7.app/repertoire/mutationCount",
37
15
  /** The variant axis's label column — shown as "Variant Id". */
38
16
  VariantLabel: "pl7.app/label",
17
+ /** The **sample** axis's label column. Same name as `VariantLabel`; the axis picks one. */
18
+ SampleLabel: "pl7.app/label",
39
19
  /** The per-variant mutation list, shown as "Mutations". */
40
20
  Mutations: "pl7.app/repertoire/mutations"
41
21
  };
@@ -103,16 +83,28 @@ const metadataSelector = {
103
83
  }],
104
84
  name: PColumnName$1.Metadata
105
85
  };
86
+ /**
87
+ * The sample axis's label column. `pl7.app/isLabel` is required alongside the name, which the
88
+ * variant label column shares.
89
+ */
90
+ const sampleLabelSelector = {
91
+ axes: [{
92
+ anchor: "main",
93
+ idx: 0
94
+ }],
95
+ name: PColumnName$1.SampleLabel,
96
+ annotations: { "pl7.app/isLabel": "true" }
97
+ };
106
98
  PColumnName$1.MutationCount;
107
99
  //#endregion
108
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/plugin_handle.js
100
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/plugin_handle.js
109
101
  const PLUGIN_OUTPUT_PREFIX = "plugin-output#";
110
102
  /** Construct the output key for a plugin output in the block outputs map. */
111
103
  function pluginOutputKey(handle, outputKey) {
112
104
  return `${PLUGIN_OUTPUT_PREFIX}${handle}#${outputKey}`;
113
105
  }
114
106
  //#endregion
115
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/block_storage.js
107
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/block_storage.js
116
108
  /**
117
109
  * Discriminator key for BlockStorage format detection.
118
110
  * This unique hash-based key identifies data as BlockStorage vs legacy formats.
@@ -354,1355 +346,727 @@ function getPluginData(rawStorage, handle) {
354
346
  return pluginEntry.__data;
355
347
  }
356
348
  //#endregion
357
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/block_migrations.js
358
- /** Create a DataVersioned wrapper with correct shape */
359
- function makeVersionedData(version, data) {
360
- return {
361
- version,
362
- data
349
+ //#region ../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.js
350
+ var util;
351
+ (function(util) {
352
+ util.assertEqual = (_) => {};
353
+ function assertIs(_arg) {}
354
+ util.assertIs = assertIs;
355
+ function assertNever(_x) {
356
+ throw new Error();
357
+ }
358
+ util.assertNever = assertNever;
359
+ util.arrayToEnum = (items) => {
360
+ const obj = {};
361
+ for (const item of items) obj[item] = item;
362
+ return obj;
363
363
  };
364
- }
365
- /** Thrown by recover() to signal unrecoverable data. */
366
- var DataUnrecoverableError = class extends Error {
367
- name = "DataUnrecoverableError";
368
- constructor(dataVersion) {
369
- super(`Unknown version '${dataVersion}'`);
364
+ util.getValidEnumValues = (obj) => {
365
+ const validKeys = util.objectKeys(obj).filter((k) => typeof obj[obj[k]] !== "number");
366
+ const filtered = {};
367
+ for (const k of validKeys) filtered[k] = obj[k];
368
+ return util.objectValues(filtered);
369
+ };
370
+ util.objectValues = (obj) => {
371
+ return util.objectKeys(obj).map(function(e) {
372
+ return obj[e];
373
+ });
374
+ };
375
+ util.objectKeys = typeof Object.keys === "function" ? (obj) => Object.keys(obj) : (object) => {
376
+ const keys = [];
377
+ for (const key in object) if (Object.prototype.hasOwnProperty.call(object, key)) keys.push(key);
378
+ return keys;
379
+ };
380
+ util.find = (arr, checker) => {
381
+ for (const item of arr) if (checker(item)) return item;
382
+ };
383
+ util.isInteger = typeof Number.isInteger === "function" ? (val) => Number.isInteger(val) : (val) => typeof val === "number" && Number.isFinite(val) && Math.floor(val) === val;
384
+ function joinValues(array, separator = " | ") {
385
+ return array.map((val) => typeof val === "string" ? `'${val}'` : val).join(separator);
386
+ }
387
+ util.joinValues = joinValues;
388
+ util.jsonStringifyReplacer = (_, value) => {
389
+ if (typeof value === "bigint") return value.toString();
390
+ return value;
391
+ };
392
+ })(util || (util = {}));
393
+ var objectUtil;
394
+ (function(objectUtil) {
395
+ objectUtil.mergeShapes = (first, second) => {
396
+ return {
397
+ ...first,
398
+ ...second
399
+ };
400
+ };
401
+ })(objectUtil || (objectUtil = {}));
402
+ const ZodParsedType = util.arrayToEnum([
403
+ "string",
404
+ "nan",
405
+ "number",
406
+ "integer",
407
+ "float",
408
+ "boolean",
409
+ "date",
410
+ "bigint",
411
+ "symbol",
412
+ "function",
413
+ "undefined",
414
+ "null",
415
+ "array",
416
+ "object",
417
+ "unknown",
418
+ "promise",
419
+ "void",
420
+ "never",
421
+ "map",
422
+ "set"
423
+ ]);
424
+ const getParsedType = (data) => {
425
+ switch (typeof data) {
426
+ case "undefined": return ZodParsedType.undefined;
427
+ case "string": return ZodParsedType.string;
428
+ case "number": return Number.isNaN(data) ? ZodParsedType.nan : ZodParsedType.number;
429
+ case "boolean": return ZodParsedType.boolean;
430
+ case "function": return ZodParsedType.function;
431
+ case "bigint": return ZodParsedType.bigint;
432
+ case "symbol": return ZodParsedType.symbol;
433
+ case "object":
434
+ if (Array.isArray(data)) return ZodParsedType.array;
435
+ if (data === null) return ZodParsedType.null;
436
+ if (data.then && typeof data.then === "function" && data.catch && typeof data.catch === "function") return ZodParsedType.promise;
437
+ if (typeof Map !== "undefined" && data instanceof Map) return ZodParsedType.map;
438
+ if (typeof Set !== "undefined" && data instanceof Set) return ZodParsedType.set;
439
+ if (typeof Date !== "undefined" && data instanceof Date) return ZodParsedType.date;
440
+ return ZodParsedType.object;
441
+ default: return ZodParsedType.unknown;
370
442
  }
371
443
  };
372
- function isDataUnrecoverableError(error) {
373
- return error instanceof Error && error.name === "DataUnrecoverableError";
374
- }
375
- /**
376
- * Default recover function for unknown versions.
377
- * Use as fallback at the end of custom recover functions.
378
- *
379
- * @example
380
- * .recover((version, data) => {
381
- * if (version === 'legacy') {
382
- * return transformLegacyData(data);
383
- * }
384
- * return defaultRecover(version, data);
385
- * })
386
- */
387
- const defaultRecover = (version, _data) => {
388
- throw new DataUnrecoverableError(version);
389
- };
390
- /** Symbol for internal builder creation method */
391
- const FROM_BUILDER = Symbol("fromBuilder");
392
- /**
393
- * Abstract base for both migration chain types.
394
- * Holds shared state, buildStep() helper, and init().
395
- * migrate() cannot be shared due to a TypeScript limitation: when the base class
396
- * migrate() return type is abstract, subclasses cannot narrow it without losing type safety.
397
- * Each subclass therefore owns its migrate() with the correct concrete return type.
398
- *
399
- * @internal
400
- */
401
- var MigrationChainBase = class {
402
- versionChain;
403
- migrationSteps;
404
- transferSteps;
405
- constructor(state) {
406
- this.versionChain = state.versionChain;
407
- this.migrationSteps = state.steps;
408
- this.transferSteps = state.transferSteps ?? [];
444
+ //#endregion
445
+ //#region ../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/ZodError.js
446
+ const ZodIssueCode = util.arrayToEnum([
447
+ "invalid_type",
448
+ "invalid_literal",
449
+ "custom",
450
+ "invalid_union",
451
+ "invalid_union_discriminator",
452
+ "invalid_enum_value",
453
+ "unrecognized_keys",
454
+ "invalid_arguments",
455
+ "invalid_return_type",
456
+ "invalid_date",
457
+ "invalid_string",
458
+ "too_small",
459
+ "too_big",
460
+ "invalid_intersection_types",
461
+ "not_multiple_of",
462
+ "not_finite"
463
+ ]);
464
+ var ZodError = class ZodError extends Error {
465
+ get errors() {
466
+ return this.issues;
409
467
  }
410
- /** Appends a migration step and returns the new versionChain and steps arrays. */
411
- buildStep(nextVersion, fn) {
412
- if (this.versionChain.includes(nextVersion)) throw new Error(`Duplicate version '${nextVersion}' in migration chain`);
413
- const step = {
414
- fromVersion: this.versionChain[this.versionChain.length - 1],
415
- toVersion: nextVersion,
416
- migrate: fn
468
+ constructor(issues) {
469
+ super();
470
+ this.issues = [];
471
+ this.addIssue = (sub) => {
472
+ this.issues = [...this.issues, sub];
417
473
  };
418
- return {
419
- versionChain: [...this.versionChain, nextVersion],
420
- steps: [...this.migrationSteps, step]
474
+ this.addIssues = (subs = []) => {
475
+ this.issues = [...this.issues, ...subs];
421
476
  };
477
+ const actualProto = new.target.prototype;
478
+ if (Object.setPrototypeOf) Object.setPrototypeOf(this, actualProto);
479
+ else this.__proto__ = actualProto;
480
+ this.name = "ZodError";
481
+ this.issues = issues;
422
482
  }
423
- /** Validates uniqueness and records a TransferStep. */
424
- buildTransfer(target, extract) {
425
- if (this.transferSteps.some((t) => t.pluginId === target.id)) throw new Error(`Duplicate transfer for plugin '${target.id}'`);
426
- const entry = {
427
- pluginId: target.id,
428
- beforeStepIndex: this.migrationSteps.length,
429
- extract,
430
- targetVersion: target.transferVersion
483
+ format(_mapper) {
484
+ const mapper = _mapper || function(issue) {
485
+ return issue.message;
431
486
  };
432
- return { transferSteps: [...this.transferSteps, entry] };
487
+ const fieldErrors = { _errors: [] };
488
+ const processError = (error) => {
489
+ for (const issue of error.issues) if (issue.code === "invalid_union") issue.unionErrors.map(processError);
490
+ else if (issue.code === "invalid_return_type") processError(issue.returnTypeError);
491
+ else if (issue.code === "invalid_arguments") processError(issue.argumentsError);
492
+ else if (issue.path.length === 0) fieldErrors._errors.push(mapper(issue));
493
+ else {
494
+ let curr = fieldErrors;
495
+ let i = 0;
496
+ while (i < issue.path.length) {
497
+ const el = issue.path[i];
498
+ if (!(i === issue.path.length - 1)) curr[el] = curr[el] || { _errors: [] };
499
+ else {
500
+ curr[el] = curr[el] || { _errors: [] };
501
+ curr[el]._errors.push(mapper(issue));
502
+ }
503
+ curr = curr[el];
504
+ i++;
505
+ }
506
+ }
507
+ };
508
+ processError(this);
509
+ return fieldErrors;
433
510
  }
434
- /** Returns recover-specific fields for DataModel construction. Overridden by WithRecover. */
435
- recoverState() {
436
- return {};
511
+ static assert(value) {
512
+ if (!(value instanceof ZodError)) throw new Error(`Not a ZodError: ${value}`);
437
513
  }
438
- /**
439
- * Finalize the DataModel with initial data factory.
440
- *
441
- * @param initialData - Factory function returning the initial state
442
- * @returns Finalized DataModel instance
443
- */
444
- init(initialData) {
445
- return DataModel[FROM_BUILDER]({
446
- versionChain: this.versionChain,
447
- steps: this.migrationSteps,
448
- transferSteps: this.transferSteps,
449
- initialDataFn: initialData,
450
- ...this.recoverState()
451
- });
514
+ toString() {
515
+ return this.message;
452
516
  }
453
- };
454
- /**
455
- * Migration chain after recover() or upgradeLegacy() has been called.
456
- * Further migrate() and transfer() calls are allowed; recover() and upgradeLegacy() are not
457
- * (enforced by type — no such methods on this class).
458
- *
459
- * @typeParam Current - Data type at the current point in the chain
460
- * @typeParam Transfers - Accumulated transfer types keyed by plugin ID
461
- * @internal
462
- */
463
- var DataModelMigrationChainWithRecover = class DataModelMigrationChainWithRecover extends MigrationChainBase {
464
- recoverFn;
465
- recoverFromIndex;
466
- /** @internal */
467
- constructor(state) {
468
- super(state);
469
- this.recoverFn = state.recoverFn;
470
- this.recoverFromIndex = state.recoverFromIndex;
517
+ get message() {
518
+ return JSON.stringify(this.issues, util.jsonStringifyReplacer, 2);
471
519
  }
472
- recoverState() {
520
+ get isEmpty() {
521
+ return this.issues.length === 0;
522
+ }
523
+ flatten(mapper = (issue) => issue.message) {
524
+ const fieldErrors = {};
525
+ const formErrors = [];
526
+ for (const sub of this.issues) if (sub.path.length > 0) {
527
+ const firstEl = sub.path[0];
528
+ fieldErrors[firstEl] = fieldErrors[firstEl] || [];
529
+ fieldErrors[firstEl].push(mapper(sub));
530
+ } else formErrors.push(mapper(sub));
473
531
  return {
474
- recoverFn: this.recoverFn,
475
- recoverFromIndex: this.recoverFromIndex
532
+ formErrors,
533
+ fieldErrors
476
534
  };
477
535
  }
478
- /**
479
- * Add a migration step. Same semantics as on the base chain.
480
- * recover() and upgradeLegacy() are not available — one has already been called.
481
- */
482
- migrate(nextVersion, fn) {
483
- const { versionChain, steps } = this.buildStep(nextVersion, fn);
484
- return new DataModelMigrationChainWithRecover({
485
- versionChain,
486
- steps,
487
- transferSteps: this.transferSteps,
488
- recoverFn: this.recoverFn,
489
- recoverFromIndex: this.recoverFromIndex
490
- });
536
+ get formErrors() {
537
+ return this.flatten();
491
538
  }
492
- /**
493
- * Extract data at the current chain position for seeding a new plugin.
494
- * The extract function's return type must match the plugin's transfer data type.
495
- * Duplicate plugin IDs are rejected at both type and runtime level.
496
- */
497
- transfer(target, extract) {
498
- const { transferSteps } = this.buildTransfer(target, extract);
499
- return new DataModelMigrationChainWithRecover({
500
- versionChain: this.versionChain,
501
- steps: this.migrationSteps,
502
- transferSteps,
503
- recoverFn: this.recoverFn,
504
- recoverFromIndex: this.recoverFromIndex
505
- });
539
+ };
540
+ ZodError.create = (issues) => {
541
+ return new ZodError(issues);
542
+ };
543
+ //#endregion
544
+ //#region ../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/locales/en.js
545
+ const errorMap = (issue, _ctx) => {
546
+ let message;
547
+ switch (issue.code) {
548
+ case ZodIssueCode.invalid_type:
549
+ if (issue.received === ZodParsedType.undefined) message = "Required";
550
+ else message = `Expected ${issue.expected}, received ${issue.received}`;
551
+ break;
552
+ case ZodIssueCode.invalid_literal:
553
+ message = `Invalid literal value, expected ${JSON.stringify(issue.expected, util.jsonStringifyReplacer)}`;
554
+ break;
555
+ case ZodIssueCode.unrecognized_keys:
556
+ message = `Unrecognized key(s) in object: ${util.joinValues(issue.keys, ", ")}`;
557
+ break;
558
+ case ZodIssueCode.invalid_union:
559
+ message = `Invalid input`;
560
+ break;
561
+ case ZodIssueCode.invalid_union_discriminator:
562
+ message = `Invalid discriminator value. Expected ${util.joinValues(issue.options)}`;
563
+ break;
564
+ case ZodIssueCode.invalid_enum_value:
565
+ message = `Invalid enum value. Expected ${util.joinValues(issue.options)}, received '${issue.received}'`;
566
+ break;
567
+ case ZodIssueCode.invalid_arguments:
568
+ message = `Invalid function arguments`;
569
+ break;
570
+ case ZodIssueCode.invalid_return_type:
571
+ message = `Invalid function return type`;
572
+ break;
573
+ case ZodIssueCode.invalid_date:
574
+ message = `Invalid date`;
575
+ break;
576
+ case ZodIssueCode.invalid_string:
577
+ if (typeof issue.validation === "object") {
578
+ if ("includes" in issue.validation) {
579
+ message = `Invalid input: must include "${issue.validation.includes}"`;
580
+ if (typeof issue.validation.position === "number") message = `${message} at one or more positions greater than or equal to ${issue.validation.position}`;
581
+ } else if ("startsWith" in issue.validation) message = `Invalid input: must start with "${issue.validation.startsWith}"`;
582
+ else if ("endsWith" in issue.validation) message = `Invalid input: must end with "${issue.validation.endsWith}"`;
583
+ else util.assertNever(issue.validation);
584
+ } else if (issue.validation !== "regex") message = `Invalid ${issue.validation}`;
585
+ else message = "Invalid";
586
+ break;
587
+ case ZodIssueCode.too_small:
588
+ if (issue.type === "array") message = `Array must contain ${issue.exact ? "exactly" : issue.inclusive ? `at least` : `more than`} ${issue.minimum} element(s)`;
589
+ else if (issue.type === "string") message = `String must contain ${issue.exact ? "exactly" : issue.inclusive ? `at least` : `over`} ${issue.minimum} character(s)`;
590
+ else if (issue.type === "number") message = `Number must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${issue.minimum}`;
591
+ else if (issue.type === "bigint") message = `Number must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${issue.minimum}`;
592
+ else if (issue.type === "date") message = `Date must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${new Date(Number(issue.minimum))}`;
593
+ else message = "Invalid input";
594
+ break;
595
+ case ZodIssueCode.too_big:
596
+ if (issue.type === "array") message = `Array must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `less than`} ${issue.maximum} element(s)`;
597
+ else if (issue.type === "string") message = `String must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `under`} ${issue.maximum} character(s)`;
598
+ else if (issue.type === "number") message = `Number must be ${issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`} ${issue.maximum}`;
599
+ else if (issue.type === "bigint") message = `BigInt must be ${issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`} ${issue.maximum}`;
600
+ else if (issue.type === "date") message = `Date must be ${issue.exact ? `exactly` : issue.inclusive ? `smaller than or equal to` : `smaller than`} ${new Date(Number(issue.maximum))}`;
601
+ else message = "Invalid input";
602
+ break;
603
+ case ZodIssueCode.custom:
604
+ message = `Invalid input`;
605
+ break;
606
+ case ZodIssueCode.invalid_intersection_types:
607
+ message = `Intersection results could not be merged`;
608
+ break;
609
+ case ZodIssueCode.not_multiple_of:
610
+ message = `Number must be a multiple of ${issue.multipleOf}`;
611
+ break;
612
+ case ZodIssueCode.not_finite:
613
+ message = "Number must be finite";
614
+ break;
615
+ default:
616
+ message = _ctx.defaultError;
617
+ util.assertNever(issue);
506
618
  }
619
+ return { message };
507
620
  };
508
- /**
509
- * Migration chain builder.
510
- * Each migrate() call advances the current data type. recover() can be called once
511
- * at any point — it removes itself from the returned chain so it cannot be called again.
512
- * Duplicate version keys throw at runtime.
513
- *
514
- * @typeParam Current - Data type at the current point in the migration chain
515
- * @typeParam Transfers - Accumulated transfer types keyed by plugin ID
516
- * @internal
517
- */
518
- var DataModelMigrationChain = class DataModelMigrationChain extends MigrationChainBase {
519
- /** @internal */
520
- constructor({ versionChain, steps = [], transferSteps = [] }) {
521
- super({
522
- versionChain,
523
- steps,
524
- transferSteps
525
- });
621
+ //#endregion
622
+ //#region ../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/errors.js
623
+ let overrideErrorMap = errorMap;
624
+ function getErrorMap() {
625
+ return overrideErrorMap;
626
+ }
627
+ //#endregion
628
+ //#region ../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
629
+ const makeIssue = (params) => {
630
+ const { data, path, errorMaps, issueData } = params;
631
+ const fullPath = [...path, ...issueData.path || []];
632
+ const fullIssue = {
633
+ ...issueData,
634
+ path: fullPath
635
+ };
636
+ if (issueData.message !== void 0) return {
637
+ ...issueData,
638
+ path: fullPath,
639
+ message: issueData.message
640
+ };
641
+ let errorMessage = "";
642
+ const maps = errorMaps.filter((m) => !!m).slice().reverse();
643
+ for (const map of maps) errorMessage = map(fullIssue, {
644
+ data,
645
+ defaultError: errorMessage
646
+ }).message;
647
+ return {
648
+ ...issueData,
649
+ path: fullPath,
650
+ message: errorMessage
651
+ };
652
+ };
653
+ function addIssueToContext(ctx, issueData) {
654
+ const overrideMap = getErrorMap();
655
+ const issue = makeIssue({
656
+ issueData,
657
+ data: ctx.data,
658
+ path: ctx.path,
659
+ errorMaps: [
660
+ ctx.common.contextualErrorMap,
661
+ ctx.schemaErrorMap,
662
+ overrideMap,
663
+ overrideMap === errorMap ? void 0 : errorMap
664
+ ].filter((x) => !!x)
665
+ });
666
+ ctx.common.issues.push(issue);
667
+ }
668
+ var ParseStatus = class ParseStatus {
669
+ constructor() {
670
+ this.value = "valid";
526
671
  }
527
- /**
528
- * Add a migration step transforming data from the current version to the next.
529
- *
530
- * @typeParam Next - Data type of the next version
531
- * @param nextVersion - Version key to migrate to (must be unique in the chain)
532
- * @param fn - Migration function
533
- * @returns Builder with the next version as current
534
- *
535
- * @example
536
- * .migrate<BlockDataV2>("v2", (v1) => ({ ...v1, labels: [] }))
537
- */
538
- migrate(nextVersion, fn) {
539
- const { versionChain, steps } = this.buildStep(nextVersion, fn);
540
- return new DataModelMigrationChain({
541
- versionChain,
542
- steps,
543
- transferSteps: this.transferSteps
544
- });
672
+ dirty() {
673
+ if (this.value === "valid") this.value = "dirty";
545
674
  }
546
- /**
547
- * Extract data at the current chain position for seeding a new plugin.
548
- * The extract function's return type must match the plugin's transfer data type.
549
- * Duplicate plugin IDs are rejected at both type and runtime level.
550
- *
551
- * Calling .transfer() on DataModelInitialChain returns DataModelMigrationChain,
552
- * which removes .upgradeLegacy() from the chain (preventing a problematic combination).
553
- *
554
- * @example
555
- * .from<V1>("v1")
556
- * .transfer(tablePlugin, (v1) => ({ state: v1.tableState }))
557
- * .migrate<V2>("v2", ({ tableState: _, ...rest }) => rest)
558
- */
559
- transfer(target, extract) {
560
- const { transferSteps } = this.buildTransfer(target, extract);
561
- return new DataModelMigrationChain({
562
- versionChain: this.versionChain,
563
- steps: this.migrationSteps,
564
- transferSteps
565
- });
675
+ abort() {
676
+ if (this.value !== "aborted") this.value = "aborted";
566
677
  }
567
- /**
568
- * Set a recovery handler for unknown or legacy versions.
569
- *
570
- * The recover function is called when data has a version not in the migration chain.
571
- * It must return data of the type at this point in the chain (Current). Any migrate()
572
- * steps added after recover() will then run on the recovered data.
573
- *
574
- * Can only be called once — the returned chain has no recover() method.
575
- *
576
- * @param fn - Recovery function returning Current (the type at this chain position)
577
- * @returns Builder with migrate() and init() but without recover()
578
- *
579
- * @example
580
- * // Recover between migrations — recovered data goes through v3 migration
581
- * new DataModelBuilder<V1>("v1")
582
- * .migrate<V2>("v2", (v1) => ({ ...v1, label: "" }))
583
- * .recover((version, data) => {
584
- * if (version === 'legacy') return transformLegacy(data); // returns V2
585
- * return defaultRecover(version, data);
586
- * })
587
- * .migrate<V3>("v3", (v2) => ({ ...v2, description: "" }))
588
- * .init(() => ({ count: 0, label: "", description: "" }));
589
- */
590
- recover(fn) {
591
- return new DataModelMigrationChainWithRecover({
592
- versionChain: this.versionChain,
593
- steps: this.migrationSteps,
594
- transferSteps: this.transferSteps,
595
- recoverFn: fn,
596
- recoverFromIndex: this.migrationSteps.length
597
- });
598
- }
599
- };
600
- /**
601
- * Initial migration chain returned by `.from()`.
602
- * Extends DataModelMigrationChain with `upgradeLegacy()` — available only before
603
- * any `.migrate()` calls, since legacy data always arrives at the initial version.
604
- *
605
- * @typeParam Current - Data type at the initial version
606
- * @typeParam Transfers - Accumulated transfer types keyed by plugin ID
607
- * @internal
608
- */
609
- var DataModelInitialChain = class extends DataModelMigrationChain {
610
- /**
611
- * Handle legacy V1 model state ({ args, uiState }) when upgrading a block from
612
- * BlockModel V1 to BlockModelV3.
613
- *
614
- * When a V1 block is upgraded, its stored state `{ args, uiState }` is normalized
615
- * to the internal default version. This method inserts a migration step from that
616
- * internal version to the version specified in `.from()`, using the provided typed
617
- * callback to transform the legacy shape. Non-legacy data passes through unchanged.
618
- *
619
- * Must be called right after `.from()` — not available after `.migrate()` calls.
620
- * Any `.migrate()` steps added after `upgradeLegacy()` will run on the transformed result.
621
- *
622
- * Can only be called once — the returned chain has no upgradeLegacy() method.
623
- * Mutually exclusive with recover().
624
- *
625
- * @typeParam Args - Type of the legacy block args
626
- * @typeParam UiState - Type of the legacy block uiState
627
- * @param fn - Typed transform from { args, uiState } to Current
628
- * @returns Builder with migrate() and init() but without recover() or upgradeLegacy()
629
- *
630
- * @example
631
- * type OldArgs = { inputFile: string; threshold: number };
632
- * type OldUiState = { selectedTab: string };
633
- * type BlockData = { inputFile: string; threshold: number; selectedTab: string };
634
- *
635
- * const dataModel = new DataModelBuilder()
636
- * .from<BlockData>("v1")
637
- * .upgradeLegacy<OldArgs, OldUiState>(({ args, uiState }) => ({
638
- * inputFile: args.inputFile,
639
- * threshold: args.threshold,
640
- * selectedTab: uiState.selectedTab,
641
- * }))
642
- * .init(() => ({ inputFile: '', threshold: 0, selectedTab: 'main' }));
643
- */
644
- upgradeLegacy(fn) {
645
- const wrappedFn = (data) => {
646
- if (data !== null && typeof data === "object" && "args" in data) return fn(data);
647
- return data;
648
- };
649
- const step = {
650
- fromVersion: DATA_MODEL_LEGACY_VERSION,
651
- toVersion: this.versionChain[0],
652
- migrate: wrappedFn
678
+ static mergeArray(status, results) {
679
+ const arrayValue = [];
680
+ for (const s of results) {
681
+ if (s.status === "aborted") return INVALID;
682
+ if (s.status === "dirty") status.dirty();
683
+ arrayValue.push(s.value);
684
+ }
685
+ return {
686
+ status: status.value,
687
+ value: arrayValue
653
688
  };
654
- return new DataModelMigrationChainWithRecover({
655
- versionChain: [DATA_MODEL_LEGACY_VERSION, ...this.versionChain],
656
- steps: [step, ...this.migrationSteps],
657
- transferSteps: this.transferSteps.map((t) => ({
658
- ...t,
659
- beforeStepIndex: t.beforeStepIndex + 1
660
- }))
661
- });
662
- }
663
- };
664
- /**
665
- * Builder entry point for creating DataModel with type-safe migrations.
666
- *
667
- * @example
668
- * // Simple (no migrations):
669
- * const dataModel = new DataModelBuilder()
670
- * .from<BlockData>("v1")
671
- * .init(() => ({ numbers: [] }));
672
- *
673
- * @example
674
- * // With migrations:
675
- * const dataModel = new DataModelBuilder()
676
- * .from<BlockDataV1>("v1")
677
- * .migrate<BlockDataV2>("v2", (v1) => ({ ...v1, labels: [] }))
678
- * .migrate<BlockDataV3>("v3", (v2) => ({ ...v2, description: '' }))
679
- * .init(() => ({ numbers: [], labels: [], description: '' }));
680
- *
681
- * @example
682
- * // With recover() between migrations — recovered data goes through remaining migrations:
683
- * const dataModelChain = new DataModelBuilder()
684
- * .from<BlockDataV1>("v1")
685
- * .migrate<BlockDataV2>("v2", (v1) => ({ ...v1, labels: [] }));
686
- *
687
- * // recover() placed before the v3 migration: recovered data goes through v3
688
- * const dataModel = dataModelChain
689
- * .recover((version, data) => {
690
- * if (version === 'legacy' && isLegacyData(data)) return transformLegacy(data); // returns V2
691
- * return defaultRecover(version, data);
692
- * })
693
- * .migrate<BlockDataV3>("v3", (v2) => ({ ...v2, description: '' }))
694
- * .init(() => ({ numbers: [], labels: [], description: '' }));
695
- *
696
- * @example
697
- * // With upgradeLegacy() — typed upgrade from BlockModel V1 state:
698
- * type OldArgs = { inputFile: string };
699
- * type OldUiState = { selectedTab: string };
700
- * type BlockData = { inputFile: string; selectedTab: string };
701
- *
702
- * const dataModel = new DataModelBuilder()
703
- * .from<BlockData>("v1")
704
- * .upgradeLegacy<OldArgs, OldUiState>(({ args, uiState }) => ({
705
- * inputFile: args.inputFile,
706
- * selectedTab: uiState.selectedTab,
707
- * }))
708
- * .init(() => ({ inputFile: '', selectedTab: 'main' }));
709
- */
710
- var DataModelBuilder = class {
711
- /**
712
- * Start the migration chain with the given initial data type and version key.
713
- *
714
- * @typeParam T - Data type for the initial version
715
- * @param initialVersion - Version key string (e.g. "v1")
716
- * @returns Migration chain builder
717
- */
718
- from(initialVersion) {
719
- return new DataModelInitialChain({ versionChain: [initialVersion] });
720
- }
721
- };
722
- /**
723
- * DataModel defines the block's data structure, initial values, and migrations.
724
- * Used by BlockModelV3 to manage data state.
725
- *
726
- * Use `new DataModelBuilder()` to create a DataModel.
727
- *
728
- * @example
729
- * // With recover() between migrations:
730
- * // Recovered data (V2) goes through the v2→v3 migration automatically.
731
- * const dataModel = new DataModelBuilder()
732
- * .from<V1>("v1")
733
- * .migrate<V2>("v2", (v1) => ({ ...v1, label: "" }))
734
- * .recover((version, data) => {
735
- * if (version === "legacy") return transformLegacy(data); // returns V2
736
- * return defaultRecover(version, data);
737
- * })
738
- * .migrate<V3>("v3", (v2) => ({ ...v2, description: "" }))
739
- * .init(() => ({ count: 0, label: "", description: "" }));
740
- */
741
- var DataModel = class DataModel {
742
- /** Latest version key — O(1) access for the common "already current" check. */
743
- latestVersion;
744
- /** Maps each known version key to the index of the first step to run from it. O(1) lookup. */
745
- stepsByFromVersion;
746
- steps;
747
- transferSteps;
748
- initialDataFn;
749
- recoverFn;
750
- recoverFromIndex;
751
- constructor({ versionChain, steps, transferSteps = [], initialDataFn, recoverFn = defaultRecover, recoverFromIndex }) {
752
- if (versionChain.length === 0) throw new Error("DataModel requires at least one version key");
753
- this.latestVersion = versionChain[versionChain.length - 1];
754
- this.stepsByFromVersion = new Map(versionChain.map((v, i) => [v, i]));
755
- this.steps = steps;
756
- this.transferSteps = transferSteps;
757
- this.initialDataFn = initialDataFn;
758
- this.recoverFn = recoverFn;
759
- this.recoverFromIndex = recoverFromIndex ?? steps.length;
760
- }
761
- /**
762
- * Internal method for creating DataModel from builder.
763
- * Uses Symbol key to prevent external access.
764
- * @internal
765
- */
766
- static [FROM_BUILDER](state) {
767
- return new DataModel(state);
768
- }
769
- /**
770
- * The latest (current) version key in the migration chain.
771
- */
772
- get version() {
773
- return this.latestVersion;
774
- }
775
- /**
776
- * Get a fresh copy of the initial data.
777
- */
778
- initialData() {
779
- return this.initialDataFn();
780
689
  }
781
- /**
782
- * Get initial data wrapped with current version.
783
- * Used when creating new blocks or resetting to defaults.
784
- */
785
- getDefaultData() {
786
- return makeVersionedData(this.latestVersion, this.initialDataFn());
690
+ static async mergeObjectAsync(status, pairs) {
691
+ const syncPairs = [];
692
+ for (const pair of pairs) {
693
+ const key = await pair.key;
694
+ const value = await pair.value;
695
+ syncPairs.push({
696
+ key,
697
+ value
698
+ });
699
+ }
700
+ return ParseStatus.mergeObjectSync(status, syncPairs);
787
701
  }
788
- recoverFrom(data, version) {
789
- let currentData = this.recoverFn(version, data);
790
- for (let i = this.recoverFromIndex; i < this.steps.length; i++) currentData = this.steps[i].migrate(currentData);
702
+ static mergeObjectSync(status, pairs) {
703
+ const finalObject = {};
704
+ for (const pair of pairs) {
705
+ const { key, value } = pair;
706
+ if (key.status === "aborted") return INVALID;
707
+ if (value.status === "aborted") return INVALID;
708
+ if (key.status === "dirty") status.dirty();
709
+ if (value.status === "dirty") status.dirty();
710
+ if (key.value !== "__proto__" && (typeof value.value !== "undefined" || pair.alwaysSet)) finalObject[key.value] = value.value;
711
+ }
791
712
  return {
792
- version: this.latestVersion,
793
- data: currentData
713
+ status: status.value,
714
+ value: finalObject
794
715
  };
795
716
  }
796
- /**
797
- * Migrate versioned data from any version to the latest.
798
- * Collects transfer extractions at their designated chain positions.
799
- *
800
- * - If version is in chain, applies needed migrations (O(1) lookup)
801
- * - If version is unknown, attempts recovery; falls back to initial data
802
- * - If a migration step fails, throws so the caller can preserve original data
803
- *
804
- * Transfers only fire during normal step-by-step migration:
805
- * - Recovery path: returns empty transfers
806
- * - Fast-path (already at latest): returns empty transfers
807
- *
808
- * @param versioned - Data with version tag
809
- * @returns Migrated data at the latest version with transfer record
810
- * @throws If a migration step from a known version fails
811
- */
812
- migrate(versioned) {
813
- const { version: fromVersion, data } = versioned;
814
- if (fromVersion === this.latestVersion) return {
815
- version: this.latestVersion,
816
- data,
817
- transfers: {}
818
- };
819
- const startIndex = this.stepsByFromVersion.get(fromVersion);
820
- if (startIndex === void 0) try {
821
- return {
822
- ...this.recoverFrom(data, fromVersion),
823
- transfers: {}
824
- };
825
- } catch {
826
- return {
827
- ...this.getDefaultData(),
828
- transfers: {}
829
- };
830
- }
831
- let currentData = data;
832
- const transfers = {};
833
- for (let i = startIndex; i < this.steps.length; i++) {
834
- for (const t of this.transferSteps) if (t.beforeStepIndex === i) transfers[t.pluginId] = {
835
- version: t.targetVersion,
836
- data: t.extract(currentData)
837
- };
838
- currentData = this.steps[i].migrate(currentData);
717
+ };
718
+ const INVALID = Object.freeze({ status: "aborted" });
719
+ const DIRTY = (value) => ({
720
+ status: "dirty",
721
+ value
722
+ });
723
+ const OK = (value) => ({
724
+ status: "valid",
725
+ value
726
+ });
727
+ const isAborted = (x) => x.status === "aborted";
728
+ const isDirty = (x) => x.status === "dirty";
729
+ const isValid = (x) => x.status === "valid";
730
+ const isAsync = (x) => typeof Promise !== "undefined" && x instanceof Promise;
731
+ //#endregion
732
+ //#region ../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.js
733
+ var errorUtil;
734
+ (function(errorUtil) {
735
+ errorUtil.errToObj = (message) => typeof message === "string" ? { message } : message || {};
736
+ errorUtil.toString = (message) => typeof message === "string" ? message : message?.message;
737
+ })(errorUtil || (errorUtil = {}));
738
+ //#endregion
739
+ //#region ../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js
740
+ var ParseInputLazyPath = class {
741
+ constructor(parent, value, path, key) {
742
+ this._cachedPath = [];
743
+ this.parent = parent;
744
+ this.data = value;
745
+ this._path = path;
746
+ this._key = key;
747
+ }
748
+ get path() {
749
+ if (!this._cachedPath.length) {
750
+ if (Array.isArray(this._key)) this._cachedPath.push(...this._path, ...this._key);
751
+ else this._cachedPath.push(...this._path, this._key);
839
752
  }
840
- for (const t of this.transferSteps) if (t.beforeStepIndex >= this.steps.length && t.beforeStepIndex >= startIndex) transfers[t.pluginId] = {
841
- version: t.targetVersion,
842
- data: t.extract(currentData)
843
- };
753
+ return this._cachedPath;
754
+ }
755
+ };
756
+ const handleResult = (ctx, result) => {
757
+ if (isValid(result)) return {
758
+ success: true,
759
+ data: result.value
760
+ };
761
+ else {
762
+ if (!ctx.common.issues.length) throw new Error("Validation failed but no issues detected.");
844
763
  return {
845
- version: this.latestVersion,
846
- data: currentData,
847
- transfers
764
+ success: false,
765
+ get error() {
766
+ if (this._error) return this._error;
767
+ const error = new ZodError(ctx.common.issues);
768
+ this._error = error;
769
+ return this._error;
770
+ }
848
771
  };
849
772
  }
850
773
  };
851
- //#endregion
852
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/internal.js
853
- /** Utility code helping to identify whether the code is running in actual UI environment */
854
- function isInUI() {
855
- return typeof globalThis.getPlatforma !== "undefined" || typeof globalThis.platforma !== "undefined";
856
- }
857
- /** Utility code helping to retrieve a platforma instance form the environment */
858
- function getPlatformaInstance(config) {
859
- if (config && typeof globalThis.getPlatforma === "function") return globalThis.getPlatforma(config);
860
- else if (typeof globalThis.platforma !== "undefined") return globalThis.platforma;
861
- else throw new Error("Can't get platforma instance.");
862
- }
863
- function tryGetCfgRenderCtx() {
864
- if (typeof globalThis.cfgRenderCtx !== "undefined") return globalThis.cfgRenderCtx;
865
- else return void 0;
866
- }
867
- function getCfgRenderCtx() {
868
- if (typeof globalThis.cfgRenderCtx !== "undefined") return globalThis.cfgRenderCtx;
869
- else throw new Error("Not in config rendering context");
870
- }
871
- function tryRegisterCallback(key, callback) {
872
- const ctx = tryGetCfgRenderCtx();
873
- if (ctx === void 0) return false;
874
- if (key in ctx.callbackRegistry) throw new Error(`Callback with key ${key} already registered.`);
875
- ctx.callbackRegistry[key] = callback;
876
- return true;
877
- }
878
- /**
879
- * Registers a callback, replacing any existing callback with the same key.
880
- * Use this for callbacks that have a default value but can be overridden.
881
- *
882
- * @param key - The callback registry key
883
- * @param callback - The callback function to register
884
- * @returns true if registered, false if not in render context
885
- */
886
- function replaceCallback(key, callback) {
887
- const ctx = tryGetCfgRenderCtx();
888
- if (ctx === void 0) return false;
889
- ctx.callbackRegistry[key] = callback;
890
- return true;
891
- }
892
- /** Creates a ConfigRenderLambda descriptor without registering a callback. */
893
- function createRenderLambda(opts) {
894
- const { handle, ...flags } = opts;
774
+ function processCreateParams(params) {
775
+ if (!params) return {};
776
+ const { errorMap, invalid_type_error, required_error, description } = params;
777
+ if (errorMap && (invalid_type_error || required_error)) throw new Error(`Can't use "invalid_type_error" or "required_error" in conjunction with custom error map.`);
778
+ if (errorMap) return {
779
+ errorMap,
780
+ description
781
+ };
782
+ const customMap = (iss, ctx) => {
783
+ const { message } = params;
784
+ if (iss.code === "invalid_enum_value") return { message: message ?? ctx.defaultError };
785
+ if (typeof ctx.data === "undefined") return { message: message ?? required_error ?? ctx.defaultError };
786
+ if (iss.code !== "invalid_type") return { message: ctx.defaultError };
787
+ return { message: message ?? invalid_type_error ?? ctx.defaultError };
788
+ };
895
789
  return {
896
- __renderLambda: true,
897
- handle,
898
- ...flags
790
+ errorMap: customMap,
791
+ description
899
792
  };
900
793
  }
901
- /** Registers a callback and returns a ConfigRenderLambda descriptor. */
902
- function createAndRegisterRenderLambda(opts, replace) {
903
- const { handle, lambda, ...flags } = opts;
904
- if (replace) replaceCallback(handle, lambda);
905
- else tryRegisterCallback(handle, lambda);
906
- return createRenderLambda({
907
- handle,
908
- ...flags
909
- });
910
- }
911
- const futureResolves = /* @__PURE__ */ new Map();
912
- function registerFutureAwait(handle, onResolve) {
913
- if (!(handle in getCfgRenderCtx().callbackRegistry)) {
914
- getCfgRenderCtx().callbackRegistry[handle] = (value) => {
915
- for (const res of futureResolves.get(handle)) res(value);
916
- };
917
- futureResolves.set(handle, []);
794
+ var ZodType = class {
795
+ get description() {
796
+ return this._def.description;
918
797
  }
919
- futureResolves.get(handle).push(onResolve);
920
- }
921
- //#endregion
922
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/block_storage_facade.js
923
- /**
924
- * All facade callback names as constants.
925
- * These are the source of truth - the interface is derived from these.
926
- *
927
- * IMPORTANT: When adding a new callback:
928
- * 1. Add the constant here
929
- * 2. Add the callback signature to FacadeCallbackTypes below
930
- * 3. The BlockStorageFacade type will automatically include it
931
- */
932
- const BlockStorageFacadeCallbacks = {
933
- StorageApplyUpdate: "__pl_storage_applyUpdate",
934
- StorageDebugView: "__pl_storage_debugView",
935
- StorageMigrate: "__pl_storage_migrate",
936
- ArgsDerive: "__pl_args_derive",
937
- PrerunArgsDerive: "__pl_prerunArgs_derive",
938
- StorageInitial: "__pl_storage_initial"
939
- };
940
- /**
941
- * Creates a map of lambda handles from a callbacks constant object.
942
- * Keys are the callback string values (e.g., '__pl_storage_applyUpdate').
943
- */
944
- function createFacadeHandles(callbacks) {
945
- return Object.fromEntries(Object.values(callbacks).map((handle) => [handle, createRenderLambda({ handle })]));
946
- }
947
- /**
948
- * Lambda handles for facade callbacks.
949
- * Used by the middle layer to invoke callbacks via executeSingleLambda().
950
- */
951
- const BlockStorageFacadeHandles = createFacadeHandles(BlockStorageFacadeCallbacks);
952
- /** Register all facade callbacks at once. Ensures all required callbacks are provided. */
953
- function registerFacadeCallbacks(callbacks) {
954
- for (const key of Object.values(BlockStorageFacadeCallbacks)) tryRegisterCallback(key, callbacks[key]);
955
- }
956
- //#endregion
957
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/render/future.js
958
- var FutureRef = class FutureRef {
959
- handle;
960
- postProcess;
961
- isResolved = false;
962
- resolvedValue;
963
- constructor(handle, postProcess = (v) => v) {
964
- this.handle = handle;
965
- this.postProcess = postProcess;
966
- registerFutureAwait(handle, (value) => {
967
- this.resolvedValue = postProcess(value);
968
- this.isResolved = true;
969
- });
798
+ _getType(input) {
799
+ return getParsedType(input.data);
970
800
  }
971
- map(mapping) {
972
- return new FutureRef(this.handle, (v) => mapping(this.postProcess(v)));
801
+ _getOrReturnCtx(input, ctx) {
802
+ return ctx || {
803
+ common: input.parent.common,
804
+ data: input.data,
805
+ parsedType: getParsedType(input.data),
806
+ schemaErrorMap: this._def.errorMap,
807
+ path: input.path,
808
+ parent: input.parent
809
+ };
973
810
  }
974
- mapDefined(mapping) {
975
- return new FutureRef(this.handle, (v) => {
976
- const vv = this.postProcess(v);
977
- return vv ? mapping(vv) : void 0;
978
- });
811
+ _processInputParams(input) {
812
+ return {
813
+ status: new ParseStatus(),
814
+ ctx: {
815
+ common: input.parent.common,
816
+ data: input.data,
817
+ parsedType: getParsedType(input.data),
818
+ schemaErrorMap: this._def.errorMap,
819
+ path: input.path,
820
+ parent: input.parent
821
+ }
822
+ };
979
823
  }
980
- toJSON() {
981
- return this.isResolved ? this.resolvedValue : { __awaited_futures__: [this.handle] };
824
+ _parseSync(input) {
825
+ const result = this._parse(input);
826
+ if (isAsync(result)) throw new Error("Synchronous parse encountered promise.");
827
+ return result;
982
828
  }
983
- };
984
- //#endregion
985
- //#region ../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.js
986
- var util;
987
- (function(util) {
988
- util.assertEqual = (_) => {};
989
- function assertIs(_arg) {}
990
- util.assertIs = assertIs;
991
- function assertNever(_x) {
992
- throw new Error();
829
+ _parseAsync(input) {
830
+ const result = this._parse(input);
831
+ return Promise.resolve(result);
993
832
  }
994
- util.assertNever = assertNever;
995
- util.arrayToEnum = (items) => {
996
- const obj = {};
997
- for (const item of items) obj[item] = item;
998
- return obj;
999
- };
1000
- util.getValidEnumValues = (obj) => {
1001
- const validKeys = util.objectKeys(obj).filter((k) => typeof obj[obj[k]] !== "number");
1002
- const filtered = {};
1003
- for (const k of validKeys) filtered[k] = obj[k];
1004
- return util.objectValues(filtered);
1005
- };
1006
- util.objectValues = (obj) => {
1007
- return util.objectKeys(obj).map(function(e) {
1008
- return obj[e];
833
+ parse(data, params) {
834
+ const result = this.safeParse(data, params);
835
+ if (result.success) return result.data;
836
+ throw result.error;
837
+ }
838
+ safeParse(data, params) {
839
+ const ctx = {
840
+ common: {
841
+ issues: [],
842
+ async: params?.async ?? false,
843
+ contextualErrorMap: params?.errorMap
844
+ },
845
+ path: params?.path || [],
846
+ schemaErrorMap: this._def.errorMap,
847
+ parent: null,
848
+ data,
849
+ parsedType: getParsedType(data)
850
+ };
851
+ const result = this._parseSync({
852
+ data,
853
+ path: ctx.path,
854
+ parent: ctx
1009
855
  });
1010
- };
1011
- util.objectKeys = typeof Object.keys === "function" ? (obj) => Object.keys(obj) : (object) => {
1012
- const keys = [];
1013
- for (const key in object) if (Object.prototype.hasOwnProperty.call(object, key)) keys.push(key);
1014
- return keys;
1015
- };
1016
- util.find = (arr, checker) => {
1017
- for (const item of arr) if (checker(item)) return item;
1018
- };
1019
- util.isInteger = typeof Number.isInteger === "function" ? (val) => Number.isInteger(val) : (val) => typeof val === "number" && Number.isFinite(val) && Math.floor(val) === val;
1020
- function joinValues(array, separator = " | ") {
1021
- return array.map((val) => typeof val === "string" ? `'${val}'` : val).join(separator);
856
+ return handleResult(ctx, result);
1022
857
  }
1023
- util.joinValues = joinValues;
1024
- util.jsonStringifyReplacer = (_, value) => {
1025
- if (typeof value === "bigint") return value.toString();
1026
- return value;
1027
- };
1028
- })(util || (util = {}));
1029
- var objectUtil;
1030
- (function(objectUtil) {
1031
- objectUtil.mergeShapes = (first, second) => {
1032
- return {
1033
- ...first,
1034
- ...second
858
+ "~validate"(data) {
859
+ const ctx = {
860
+ common: {
861
+ issues: [],
862
+ async: !!this["~standard"].async
863
+ },
864
+ path: [],
865
+ schemaErrorMap: this._def.errorMap,
866
+ parent: null,
867
+ data,
868
+ parsedType: getParsedType(data)
1035
869
  };
1036
- };
1037
- })(objectUtil || (objectUtil = {}));
1038
- const ZodParsedType = util.arrayToEnum([
1039
- "string",
1040
- "nan",
1041
- "number",
1042
- "integer",
1043
- "float",
1044
- "boolean",
1045
- "date",
1046
- "bigint",
1047
- "symbol",
1048
- "function",
1049
- "undefined",
1050
- "null",
1051
- "array",
1052
- "object",
1053
- "unknown",
1054
- "promise",
1055
- "void",
1056
- "never",
1057
- "map",
1058
- "set"
1059
- ]);
1060
- const getParsedType = (data) => {
1061
- switch (typeof data) {
1062
- case "undefined": return ZodParsedType.undefined;
1063
- case "string": return ZodParsedType.string;
1064
- case "number": return Number.isNaN(data) ? ZodParsedType.nan : ZodParsedType.number;
1065
- case "boolean": return ZodParsedType.boolean;
1066
- case "function": return ZodParsedType.function;
1067
- case "bigint": return ZodParsedType.bigint;
1068
- case "symbol": return ZodParsedType.symbol;
1069
- case "object":
1070
- if (Array.isArray(data)) return ZodParsedType.array;
1071
- if (data === null) return ZodParsedType.null;
1072
- if (data.then && typeof data.then === "function" && data.catch && typeof data.catch === "function") return ZodParsedType.promise;
1073
- if (typeof Map !== "undefined" && data instanceof Map) return ZodParsedType.map;
1074
- if (typeof Set !== "undefined" && data instanceof Set) return ZodParsedType.set;
1075
- if (typeof Date !== "undefined" && data instanceof Date) return ZodParsedType.date;
1076
- return ZodParsedType.object;
1077
- default: return ZodParsedType.unknown;
870
+ if (!this["~standard"].async) try {
871
+ const result = this._parseSync({
872
+ data,
873
+ path: [],
874
+ parent: ctx
875
+ });
876
+ return isValid(result) ? { value: result.value } : { issues: ctx.common.issues };
877
+ } catch (err) {
878
+ if (err?.message?.toLowerCase()?.includes("encountered")) this["~standard"].async = true;
879
+ ctx.common = {
880
+ issues: [],
881
+ async: true
882
+ };
883
+ }
884
+ return this._parseAsync({
885
+ data,
886
+ path: [],
887
+ parent: ctx
888
+ }).then((result) => isValid(result) ? { value: result.value } : { issues: ctx.common.issues });
1078
889
  }
1079
- };
1080
- //#endregion
1081
- //#region ../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/ZodError.js
1082
- const ZodIssueCode = util.arrayToEnum([
1083
- "invalid_type",
1084
- "invalid_literal",
1085
- "custom",
1086
- "invalid_union",
1087
- "invalid_union_discriminator",
1088
- "invalid_enum_value",
1089
- "unrecognized_keys",
1090
- "invalid_arguments",
1091
- "invalid_return_type",
1092
- "invalid_date",
1093
- "invalid_string",
1094
- "too_small",
1095
- "too_big",
1096
- "invalid_intersection_types",
1097
- "not_multiple_of",
1098
- "not_finite"
1099
- ]);
1100
- var ZodError = class ZodError extends Error {
1101
- get errors() {
1102
- return this.issues;
890
+ async parseAsync(data, params) {
891
+ const result = await this.safeParseAsync(data, params);
892
+ if (result.success) return result.data;
893
+ throw result.error;
1103
894
  }
1104
- constructor(issues) {
1105
- super();
1106
- this.issues = [];
1107
- this.addIssue = (sub) => {
1108
- this.issues = [...this.issues, sub];
1109
- };
1110
- this.addIssues = (subs = []) => {
1111
- this.issues = [...this.issues, ...subs];
895
+ async safeParseAsync(data, params) {
896
+ const ctx = {
897
+ common: {
898
+ issues: [],
899
+ contextualErrorMap: params?.errorMap,
900
+ async: true
901
+ },
902
+ path: params?.path || [],
903
+ schemaErrorMap: this._def.errorMap,
904
+ parent: null,
905
+ data,
906
+ parsedType: getParsedType(data)
1112
907
  };
1113
- const actualProto = new.target.prototype;
1114
- if (Object.setPrototypeOf) Object.setPrototypeOf(this, actualProto);
1115
- else this.__proto__ = actualProto;
1116
- this.name = "ZodError";
1117
- this.issues = issues;
908
+ const maybeAsyncResult = this._parse({
909
+ data,
910
+ path: ctx.path,
911
+ parent: ctx
912
+ });
913
+ const result = await (isAsync(maybeAsyncResult) ? maybeAsyncResult : Promise.resolve(maybeAsyncResult));
914
+ return handleResult(ctx, result);
1118
915
  }
1119
- format(_mapper) {
1120
- const mapper = _mapper || function(issue) {
1121
- return issue.message;
1122
- };
1123
- const fieldErrors = { _errors: [] };
1124
- const processError = (error) => {
1125
- for (const issue of error.issues) if (issue.code === "invalid_union") issue.unionErrors.map(processError);
1126
- else if (issue.code === "invalid_return_type") processError(issue.returnTypeError);
1127
- else if (issue.code === "invalid_arguments") processError(issue.argumentsError);
1128
- else if (issue.path.length === 0) fieldErrors._errors.push(mapper(issue));
1129
- else {
1130
- let curr = fieldErrors;
1131
- let i = 0;
1132
- while (i < issue.path.length) {
1133
- const el = issue.path[i];
1134
- if (!(i === issue.path.length - 1)) curr[el] = curr[el] || { _errors: [] };
1135
- else {
1136
- curr[el] = curr[el] || { _errors: [] };
1137
- curr[el]._errors.push(mapper(issue));
1138
- }
1139
- curr = curr[el];
1140
- i++;
1141
- }
1142
- }
916
+ refine(check, message) {
917
+ const getIssueProperties = (val) => {
918
+ if (typeof message === "string" || typeof message === "undefined") return { message };
919
+ else if (typeof message === "function") return message(val);
920
+ else return message;
1143
921
  };
1144
- processError(this);
1145
- return fieldErrors;
1146
- }
1147
- static assert(value) {
1148
- if (!(value instanceof ZodError)) throw new Error(`Not a ZodError: ${value}`);
922
+ return this._refinement((val, ctx) => {
923
+ const result = check(val);
924
+ const setError = () => ctx.addIssue({
925
+ code: ZodIssueCode.custom,
926
+ ...getIssueProperties(val)
927
+ });
928
+ if (typeof Promise !== "undefined" && result instanceof Promise) return result.then((data) => {
929
+ if (!data) {
930
+ setError();
931
+ return false;
932
+ } else return true;
933
+ });
934
+ if (!result) {
935
+ setError();
936
+ return false;
937
+ } else return true;
938
+ });
1149
939
  }
1150
- toString() {
1151
- return this.message;
940
+ refinement(check, refinementData) {
941
+ return this._refinement((val, ctx) => {
942
+ if (!check(val)) {
943
+ ctx.addIssue(typeof refinementData === "function" ? refinementData(val, ctx) : refinementData);
944
+ return false;
945
+ } else return true;
946
+ });
1152
947
  }
1153
- get message() {
1154
- return JSON.stringify(this.issues, util.jsonStringifyReplacer, 2);
948
+ _refinement(refinement) {
949
+ return new ZodEffects({
950
+ schema: this,
951
+ typeName: ZodFirstPartyTypeKind.ZodEffects,
952
+ effect: {
953
+ type: "refinement",
954
+ refinement
955
+ }
956
+ });
1155
957
  }
1156
- get isEmpty() {
1157
- return this.issues.length === 0;
958
+ superRefine(refinement) {
959
+ return this._refinement(refinement);
1158
960
  }
1159
- flatten(mapper = (issue) => issue.message) {
1160
- const fieldErrors = {};
1161
- const formErrors = [];
1162
- for (const sub of this.issues) if (sub.path.length > 0) {
1163
- const firstEl = sub.path[0];
1164
- fieldErrors[firstEl] = fieldErrors[firstEl] || [];
1165
- fieldErrors[firstEl].push(mapper(sub));
1166
- } else formErrors.push(mapper(sub));
1167
- return {
1168
- formErrors,
1169
- fieldErrors
961
+ constructor(def) {
962
+ /** Alias of safeParseAsync */
963
+ this.spa = this.safeParseAsync;
964
+ this._def = def;
965
+ this.parse = this.parse.bind(this);
966
+ this.safeParse = this.safeParse.bind(this);
967
+ this.parseAsync = this.parseAsync.bind(this);
968
+ this.safeParseAsync = this.safeParseAsync.bind(this);
969
+ this.spa = this.spa.bind(this);
970
+ this.refine = this.refine.bind(this);
971
+ this.refinement = this.refinement.bind(this);
972
+ this.superRefine = this.superRefine.bind(this);
973
+ this.optional = this.optional.bind(this);
974
+ this.nullable = this.nullable.bind(this);
975
+ this.nullish = this.nullish.bind(this);
976
+ this.array = this.array.bind(this);
977
+ this.promise = this.promise.bind(this);
978
+ this.or = this.or.bind(this);
979
+ this.and = this.and.bind(this);
980
+ this.transform = this.transform.bind(this);
981
+ this.brand = this.brand.bind(this);
982
+ this.default = this.default.bind(this);
983
+ this.catch = this.catch.bind(this);
984
+ this.describe = this.describe.bind(this);
985
+ this.pipe = this.pipe.bind(this);
986
+ this.readonly = this.readonly.bind(this);
987
+ this.isNullable = this.isNullable.bind(this);
988
+ this.isOptional = this.isOptional.bind(this);
989
+ this["~standard"] = {
990
+ version: 1,
991
+ vendor: "zod",
992
+ validate: (data) => this["~validate"](data)
1170
993
  };
1171
994
  }
1172
- get formErrors() {
1173
- return this.flatten();
1174
- }
1175
- };
1176
- ZodError.create = (issues) => {
1177
- return new ZodError(issues);
1178
- };
1179
- //#endregion
1180
- //#region ../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/locales/en.js
1181
- const errorMap = (issue, _ctx) => {
1182
- let message;
1183
- switch (issue.code) {
1184
- case ZodIssueCode.invalid_type:
1185
- if (issue.received === ZodParsedType.undefined) message = "Required";
1186
- else message = `Expected ${issue.expected}, received ${issue.received}`;
1187
- break;
1188
- case ZodIssueCode.invalid_literal:
1189
- message = `Invalid literal value, expected ${JSON.stringify(issue.expected, util.jsonStringifyReplacer)}`;
1190
- break;
1191
- case ZodIssueCode.unrecognized_keys:
1192
- message = `Unrecognized key(s) in object: ${util.joinValues(issue.keys, ", ")}`;
1193
- break;
1194
- case ZodIssueCode.invalid_union:
1195
- message = `Invalid input`;
1196
- break;
1197
- case ZodIssueCode.invalid_union_discriminator:
1198
- message = `Invalid discriminator value. Expected ${util.joinValues(issue.options)}`;
1199
- break;
1200
- case ZodIssueCode.invalid_enum_value:
1201
- message = `Invalid enum value. Expected ${util.joinValues(issue.options)}, received '${issue.received}'`;
1202
- break;
1203
- case ZodIssueCode.invalid_arguments:
1204
- message = `Invalid function arguments`;
1205
- break;
1206
- case ZodIssueCode.invalid_return_type:
1207
- message = `Invalid function return type`;
1208
- break;
1209
- case ZodIssueCode.invalid_date:
1210
- message = `Invalid date`;
1211
- break;
1212
- case ZodIssueCode.invalid_string:
1213
- if (typeof issue.validation === "object") {
1214
- if ("includes" in issue.validation) {
1215
- message = `Invalid input: must include "${issue.validation.includes}"`;
1216
- if (typeof issue.validation.position === "number") message = `${message} at one or more positions greater than or equal to ${issue.validation.position}`;
1217
- } else if ("startsWith" in issue.validation) message = `Invalid input: must start with "${issue.validation.startsWith}"`;
1218
- else if ("endsWith" in issue.validation) message = `Invalid input: must end with "${issue.validation.endsWith}"`;
1219
- else util.assertNever(issue.validation);
1220
- } else if (issue.validation !== "regex") message = `Invalid ${issue.validation}`;
1221
- else message = "Invalid";
1222
- break;
1223
- case ZodIssueCode.too_small:
1224
- if (issue.type === "array") message = `Array must contain ${issue.exact ? "exactly" : issue.inclusive ? `at least` : `more than`} ${issue.minimum} element(s)`;
1225
- else if (issue.type === "string") message = `String must contain ${issue.exact ? "exactly" : issue.inclusive ? `at least` : `over`} ${issue.minimum} character(s)`;
1226
- else if (issue.type === "number") message = `Number must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${issue.minimum}`;
1227
- else if (issue.type === "bigint") message = `Number must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${issue.minimum}`;
1228
- else if (issue.type === "date") message = `Date must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${new Date(Number(issue.minimum))}`;
1229
- else message = "Invalid input";
1230
- break;
1231
- case ZodIssueCode.too_big:
1232
- if (issue.type === "array") message = `Array must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `less than`} ${issue.maximum} element(s)`;
1233
- else if (issue.type === "string") message = `String must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `under`} ${issue.maximum} character(s)`;
1234
- else if (issue.type === "number") message = `Number must be ${issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`} ${issue.maximum}`;
1235
- else if (issue.type === "bigint") message = `BigInt must be ${issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`} ${issue.maximum}`;
1236
- else if (issue.type === "date") message = `Date must be ${issue.exact ? `exactly` : issue.inclusive ? `smaller than or equal to` : `smaller than`} ${new Date(Number(issue.maximum))}`;
1237
- else message = "Invalid input";
1238
- break;
1239
- case ZodIssueCode.custom:
1240
- message = `Invalid input`;
1241
- break;
1242
- case ZodIssueCode.invalid_intersection_types:
1243
- message = `Intersection results could not be merged`;
1244
- break;
1245
- case ZodIssueCode.not_multiple_of:
1246
- message = `Number must be a multiple of ${issue.multipleOf}`;
1247
- break;
1248
- case ZodIssueCode.not_finite:
1249
- message = "Number must be finite";
1250
- break;
1251
- default:
1252
- message = _ctx.defaultError;
1253
- util.assertNever(issue);
995
+ optional() {
996
+ return ZodOptional.create(this, this._def);
1254
997
  }
1255
- return { message };
1256
- };
1257
- //#endregion
1258
- //#region ../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/errors.js
1259
- let overrideErrorMap = errorMap;
1260
- function getErrorMap() {
1261
- return overrideErrorMap;
1262
- }
1263
- //#endregion
1264
- //#region ../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
1265
- const makeIssue = (params) => {
1266
- const { data, path, errorMaps, issueData } = params;
1267
- const fullPath = [...path, ...issueData.path || []];
1268
- const fullIssue = {
1269
- ...issueData,
1270
- path: fullPath
1271
- };
1272
- if (issueData.message !== void 0) return {
1273
- ...issueData,
1274
- path: fullPath,
1275
- message: issueData.message
1276
- };
1277
- let errorMessage = "";
1278
- const maps = errorMaps.filter((m) => !!m).slice().reverse();
1279
- for (const map of maps) errorMessage = map(fullIssue, {
1280
- data,
1281
- defaultError: errorMessage
1282
- }).message;
1283
- return {
1284
- ...issueData,
1285
- path: fullPath,
1286
- message: errorMessage
1287
- };
1288
- };
1289
- function addIssueToContext(ctx, issueData) {
1290
- const overrideMap = getErrorMap();
1291
- const issue = makeIssue({
1292
- issueData,
1293
- data: ctx.data,
1294
- path: ctx.path,
1295
- errorMaps: [
1296
- ctx.common.contextualErrorMap,
1297
- ctx.schemaErrorMap,
1298
- overrideMap,
1299
- overrideMap === errorMap ? void 0 : errorMap
1300
- ].filter((x) => !!x)
1301
- });
1302
- ctx.common.issues.push(issue);
1303
- }
1304
- var ParseStatus = class ParseStatus {
1305
- constructor() {
1306
- this.value = "valid";
998
+ nullable() {
999
+ return ZodNullable.create(this, this._def);
1307
1000
  }
1308
- dirty() {
1309
- if (this.value === "valid") this.value = "dirty";
1001
+ nullish() {
1002
+ return this.nullable().optional();
1310
1003
  }
1311
- abort() {
1312
- if (this.value !== "aborted") this.value = "aborted";
1004
+ array() {
1005
+ return ZodArray.create(this);
1313
1006
  }
1314
- static mergeArray(status, results) {
1315
- const arrayValue = [];
1316
- for (const s of results) {
1317
- if (s.status === "aborted") return INVALID;
1318
- if (s.status === "dirty") status.dirty();
1319
- arrayValue.push(s.value);
1320
- }
1321
- return {
1322
- status: status.value,
1323
- value: arrayValue
1324
- };
1007
+ promise() {
1008
+ return ZodPromise.create(this, this._def);
1325
1009
  }
1326
- static async mergeObjectAsync(status, pairs) {
1327
- const syncPairs = [];
1328
- for (const pair of pairs) {
1329
- const key = await pair.key;
1330
- const value = await pair.value;
1331
- syncPairs.push({
1332
- key,
1333
- value
1334
- });
1335
- }
1336
- return ParseStatus.mergeObjectSync(status, syncPairs);
1010
+ or(option) {
1011
+ return ZodUnion.create([this, option], this._def);
1337
1012
  }
1338
- static mergeObjectSync(status, pairs) {
1339
- const finalObject = {};
1340
- for (const pair of pairs) {
1341
- const { key, value } = pair;
1342
- if (key.status === "aborted") return INVALID;
1343
- if (value.status === "aborted") return INVALID;
1344
- if (key.status === "dirty") status.dirty();
1345
- if (value.status === "dirty") status.dirty();
1346
- if (key.value !== "__proto__" && (typeof value.value !== "undefined" || pair.alwaysSet)) finalObject[key.value] = value.value;
1347
- }
1348
- return {
1349
- status: status.value,
1350
- value: finalObject
1351
- };
1013
+ and(incoming) {
1014
+ return ZodIntersection.create(this, incoming, this._def);
1352
1015
  }
1353
- };
1354
- const INVALID = Object.freeze({ status: "aborted" });
1355
- const DIRTY = (value) => ({
1356
- status: "dirty",
1357
- value
1358
- });
1359
- const OK = (value) => ({
1360
- status: "valid",
1361
- value
1362
- });
1363
- const isAborted = (x) => x.status === "aborted";
1364
- const isDirty = (x) => x.status === "dirty";
1365
- const isValid = (x) => x.status === "valid";
1366
- const isAsync = (x) => typeof Promise !== "undefined" && x instanceof Promise;
1367
- //#endregion
1368
- //#region ../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.js
1369
- var errorUtil;
1370
- (function(errorUtil) {
1371
- errorUtil.errToObj = (message) => typeof message === "string" ? { message } : message || {};
1372
- errorUtil.toString = (message) => typeof message === "string" ? message : message?.message;
1373
- })(errorUtil || (errorUtil = {}));
1374
- //#endregion
1375
- //#region ../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js
1376
- var ParseInputLazyPath = class {
1377
- constructor(parent, value, path, key) {
1378
- this._cachedPath = [];
1379
- this.parent = parent;
1380
- this.data = value;
1381
- this._path = path;
1382
- this._key = key;
1383
- }
1384
- get path() {
1385
- if (!this._cachedPath.length) {
1386
- if (Array.isArray(this._key)) this._cachedPath.push(...this._path, ...this._key);
1387
- else this._cachedPath.push(...this._path, this._key);
1388
- }
1389
- return this._cachedPath;
1390
- }
1391
- };
1392
- const handleResult = (ctx, result) => {
1393
- if (isValid(result)) return {
1394
- success: true,
1395
- data: result.value
1396
- };
1397
- else {
1398
- if (!ctx.common.issues.length) throw new Error("Validation failed but no issues detected.");
1399
- return {
1400
- success: false,
1401
- get error() {
1402
- if (this._error) return this._error;
1403
- const error = new ZodError(ctx.common.issues);
1404
- this._error = error;
1405
- return this._error;
1406
- }
1407
- };
1408
- }
1409
- };
1410
- function processCreateParams(params) {
1411
- if (!params) return {};
1412
- const { errorMap, invalid_type_error, required_error, description } = params;
1413
- if (errorMap && (invalid_type_error || required_error)) throw new Error(`Can't use "invalid_type_error" or "required_error" in conjunction with custom error map.`);
1414
- if (errorMap) return {
1415
- errorMap,
1416
- description
1417
- };
1418
- const customMap = (iss, ctx) => {
1419
- const { message } = params;
1420
- if (iss.code === "invalid_enum_value") return { message: message ?? ctx.defaultError };
1421
- if (typeof ctx.data === "undefined") return { message: message ?? required_error ?? ctx.defaultError };
1422
- if (iss.code !== "invalid_type") return { message: ctx.defaultError };
1423
- return { message: message ?? invalid_type_error ?? ctx.defaultError };
1424
- };
1425
- return {
1426
- errorMap: customMap,
1427
- description
1428
- };
1429
- }
1430
- var ZodType = class {
1431
- get description() {
1432
- return this._def.description;
1433
- }
1434
- _getType(input) {
1435
- return getParsedType(input.data);
1436
- }
1437
- _getOrReturnCtx(input, ctx) {
1438
- return ctx || {
1439
- common: input.parent.common,
1440
- data: input.data,
1441
- parsedType: getParsedType(input.data),
1442
- schemaErrorMap: this._def.errorMap,
1443
- path: input.path,
1444
- parent: input.parent
1445
- };
1446
- }
1447
- _processInputParams(input) {
1448
- return {
1449
- status: new ParseStatus(),
1450
- ctx: {
1451
- common: input.parent.common,
1452
- data: input.data,
1453
- parsedType: getParsedType(input.data),
1454
- schemaErrorMap: this._def.errorMap,
1455
- path: input.path,
1456
- parent: input.parent
1016
+ transform(transform) {
1017
+ return new ZodEffects({
1018
+ ...processCreateParams(this._def),
1019
+ schema: this,
1020
+ typeName: ZodFirstPartyTypeKind.ZodEffects,
1021
+ effect: {
1022
+ type: "transform",
1023
+ transform
1457
1024
  }
1458
- };
1025
+ });
1459
1026
  }
1460
- _parseSync(input) {
1461
- const result = this._parse(input);
1462
- if (isAsync(result)) throw new Error("Synchronous parse encountered promise.");
1463
- return result;
1027
+ default(def) {
1028
+ const defaultValueFunc = typeof def === "function" ? def : () => def;
1029
+ return new ZodDefault({
1030
+ ...processCreateParams(this._def),
1031
+ innerType: this,
1032
+ defaultValue: defaultValueFunc,
1033
+ typeName: ZodFirstPartyTypeKind.ZodDefault
1034
+ });
1464
1035
  }
1465
- _parseAsync(input) {
1466
- const result = this._parse(input);
1467
- return Promise.resolve(result);
1036
+ brand() {
1037
+ return new ZodBranded({
1038
+ typeName: ZodFirstPartyTypeKind.ZodBranded,
1039
+ type: this,
1040
+ ...processCreateParams(this._def)
1041
+ });
1468
1042
  }
1469
- parse(data, params) {
1470
- const result = this.safeParse(data, params);
1471
- if (result.success) return result.data;
1472
- throw result.error;
1043
+ catch(def) {
1044
+ const catchValueFunc = typeof def === "function" ? def : () => def;
1045
+ return new ZodCatch({
1046
+ ...processCreateParams(this._def),
1047
+ innerType: this,
1048
+ catchValue: catchValueFunc,
1049
+ typeName: ZodFirstPartyTypeKind.ZodCatch
1050
+ });
1473
1051
  }
1474
- safeParse(data, params) {
1475
- const ctx = {
1476
- common: {
1477
- issues: [],
1478
- async: params?.async ?? false,
1479
- contextualErrorMap: params?.errorMap
1480
- },
1481
- path: params?.path || [],
1482
- schemaErrorMap: this._def.errorMap,
1483
- parent: null,
1484
- data,
1485
- parsedType: getParsedType(data)
1486
- };
1487
- const result = this._parseSync({
1488
- data,
1489
- path: ctx.path,
1490
- parent: ctx
1052
+ describe(description) {
1053
+ const This = this.constructor;
1054
+ return new This({
1055
+ ...this._def,
1056
+ description
1491
1057
  });
1492
- return handleResult(ctx, result);
1493
1058
  }
1494
- "~validate"(data) {
1495
- const ctx = {
1496
- common: {
1497
- issues: [],
1498
- async: !!this["~standard"].async
1499
- },
1500
- path: [],
1501
- schemaErrorMap: this._def.errorMap,
1502
- parent: null,
1503
- data,
1504
- parsedType: getParsedType(data)
1505
- };
1506
- if (!this["~standard"].async) try {
1507
- const result = this._parseSync({
1508
- data,
1509
- path: [],
1510
- parent: ctx
1511
- });
1512
- return isValid(result) ? { value: result.value } : { issues: ctx.common.issues };
1513
- } catch (err) {
1514
- if (err?.message?.toLowerCase()?.includes("encountered")) this["~standard"].async = true;
1515
- ctx.common = {
1516
- issues: [],
1517
- async: true
1518
- };
1519
- }
1520
- return this._parseAsync({
1521
- data,
1522
- path: [],
1523
- parent: ctx
1524
- }).then((result) => isValid(result) ? { value: result.value } : { issues: ctx.common.issues });
1059
+ pipe(target) {
1060
+ return ZodPipeline.create(this, target);
1525
1061
  }
1526
- async parseAsync(data, params) {
1527
- const result = await this.safeParseAsync(data, params);
1528
- if (result.success) return result.data;
1529
- throw result.error;
1062
+ readonly() {
1063
+ return ZodReadonly.create(this);
1530
1064
  }
1531
- async safeParseAsync(data, params) {
1532
- const ctx = {
1533
- common: {
1534
- issues: [],
1535
- contextualErrorMap: params?.errorMap,
1536
- async: true
1537
- },
1538
- path: params?.path || [],
1539
- schemaErrorMap: this._def.errorMap,
1540
- parent: null,
1541
- data,
1542
- parsedType: getParsedType(data)
1543
- };
1544
- const maybeAsyncResult = this._parse({
1545
- data,
1546
- path: ctx.path,
1547
- parent: ctx
1548
- });
1549
- const result = await (isAsync(maybeAsyncResult) ? maybeAsyncResult : Promise.resolve(maybeAsyncResult));
1550
- return handleResult(ctx, result);
1065
+ isOptional() {
1066
+ return this.safeParse(void 0).success;
1551
1067
  }
1552
- refine(check, message) {
1553
- const getIssueProperties = (val) => {
1554
- if (typeof message === "string" || typeof message === "undefined") return { message };
1555
- else if (typeof message === "function") return message(val);
1556
- else return message;
1557
- };
1558
- return this._refinement((val, ctx) => {
1559
- const result = check(val);
1560
- const setError = () => ctx.addIssue({
1561
- code: ZodIssueCode.custom,
1562
- ...getIssueProperties(val)
1563
- });
1564
- if (typeof Promise !== "undefined" && result instanceof Promise) return result.then((data) => {
1565
- if (!data) {
1566
- setError();
1567
- return false;
1568
- } else return true;
1569
- });
1570
- if (!result) {
1571
- setError();
1572
- return false;
1573
- } else return true;
1574
- });
1575
- }
1576
- refinement(check, refinementData) {
1577
- return this._refinement((val, ctx) => {
1578
- if (!check(val)) {
1579
- ctx.addIssue(typeof refinementData === "function" ? refinementData(val, ctx) : refinementData);
1580
- return false;
1581
- } else return true;
1582
- });
1583
- }
1584
- _refinement(refinement) {
1585
- return new ZodEffects({
1586
- schema: this,
1587
- typeName: ZodFirstPartyTypeKind.ZodEffects,
1588
- effect: {
1589
- type: "refinement",
1590
- refinement
1591
- }
1592
- });
1593
- }
1594
- superRefine(refinement) {
1595
- return this._refinement(refinement);
1596
- }
1597
- constructor(def) {
1598
- /** Alias of safeParseAsync */
1599
- this.spa = this.safeParseAsync;
1600
- this._def = def;
1601
- this.parse = this.parse.bind(this);
1602
- this.safeParse = this.safeParse.bind(this);
1603
- this.parseAsync = this.parseAsync.bind(this);
1604
- this.safeParseAsync = this.safeParseAsync.bind(this);
1605
- this.spa = this.spa.bind(this);
1606
- this.refine = this.refine.bind(this);
1607
- this.refinement = this.refinement.bind(this);
1608
- this.superRefine = this.superRefine.bind(this);
1609
- this.optional = this.optional.bind(this);
1610
- this.nullable = this.nullable.bind(this);
1611
- this.nullish = this.nullish.bind(this);
1612
- this.array = this.array.bind(this);
1613
- this.promise = this.promise.bind(this);
1614
- this.or = this.or.bind(this);
1615
- this.and = this.and.bind(this);
1616
- this.transform = this.transform.bind(this);
1617
- this.brand = this.brand.bind(this);
1618
- this.default = this.default.bind(this);
1619
- this.catch = this.catch.bind(this);
1620
- this.describe = this.describe.bind(this);
1621
- this.pipe = this.pipe.bind(this);
1622
- this.readonly = this.readonly.bind(this);
1623
- this.isNullable = this.isNullable.bind(this);
1624
- this.isOptional = this.isOptional.bind(this);
1625
- this["~standard"] = {
1626
- version: 1,
1627
- vendor: "zod",
1628
- validate: (data) => this["~validate"](data)
1629
- };
1630
- }
1631
- optional() {
1632
- return ZodOptional.create(this, this._def);
1633
- }
1634
- nullable() {
1635
- return ZodNullable.create(this, this._def);
1636
- }
1637
- nullish() {
1638
- return this.nullable().optional();
1639
- }
1640
- array() {
1641
- return ZodArray.create(this);
1642
- }
1643
- promise() {
1644
- return ZodPromise.create(this, this._def);
1645
- }
1646
- or(option) {
1647
- return ZodUnion.create([this, option], this._def);
1648
- }
1649
- and(incoming) {
1650
- return ZodIntersection.create(this, incoming, this._def);
1651
- }
1652
- transform(transform) {
1653
- return new ZodEffects({
1654
- ...processCreateParams(this._def),
1655
- schema: this,
1656
- typeName: ZodFirstPartyTypeKind.ZodEffects,
1657
- effect: {
1658
- type: "transform",
1659
- transform
1660
- }
1661
- });
1662
- }
1663
- default(def) {
1664
- const defaultValueFunc = typeof def === "function" ? def : () => def;
1665
- return new ZodDefault({
1666
- ...processCreateParams(this._def),
1667
- innerType: this,
1668
- defaultValue: defaultValueFunc,
1669
- typeName: ZodFirstPartyTypeKind.ZodDefault
1670
- });
1671
- }
1672
- brand() {
1673
- return new ZodBranded({
1674
- typeName: ZodFirstPartyTypeKind.ZodBranded,
1675
- type: this,
1676
- ...processCreateParams(this._def)
1677
- });
1678
- }
1679
- catch(def) {
1680
- const catchValueFunc = typeof def === "function" ? def : () => def;
1681
- return new ZodCatch({
1682
- ...processCreateParams(this._def),
1683
- innerType: this,
1684
- catchValue: catchValueFunc,
1685
- typeName: ZodFirstPartyTypeKind.ZodCatch
1686
- });
1687
- }
1688
- describe(description) {
1689
- const This = this.constructor;
1690
- return new This({
1691
- ...this._def,
1692
- description
1693
- });
1694
- }
1695
- pipe(target) {
1696
- return ZodPipeline.create(this, target);
1697
- }
1698
- readonly() {
1699
- return ZodReadonly.create(this);
1700
- }
1701
- isOptional() {
1702
- return this.safeParse(void 0).success;
1703
- }
1704
- isNullable() {
1705
- return this.safeParse(null).success;
1068
+ isNullable() {
1069
+ return this.safeParse(null).success;
1706
1070
  }
1707
1071
  };
1708
1072
  const cuidRegex = /^c[^\s-]{8,}$/i;
@@ -4534,6 +3898,16 @@ objectType({
4534
3898
  type: literalType("plain"),
4535
3899
  content: stringType()
4536
3900
  });
3901
+ //#endregion
3902
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/bmodel/block_kind_ref.js
3903
+ /**
3904
+ * Compose a {@link BlockKindReference} from a kind's `name`/`version`.
3905
+ *
3906
+ * The single place that decides how the reference is assembled. If global
3907
+ * uniqueness later requires the name segment to be org-qualified, this is the
3908
+ * one line that changes.
3909
+ */
3910
+ const formatKindRef = (k) => `${k.name}@${k.version}`;
4537
3911
  objectType({
4538
3912
  /** Included left border. */
4539
3913
  from: numberType().min(0),
@@ -4541,7 +3915,7 @@ objectType({
4541
3915
  to: numberType().min(1)
4542
3916
  });
4543
3917
  //#endregion
4544
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.3/node_modules/@milaboratories/pl-model-common/dist/util.js
3918
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/util.js
4545
3919
  function assertNever(x) {
4546
3920
  throw new Error("Unexpected object: " + x);
4547
3921
  }
@@ -4553,7 +3927,7 @@ function uniqueBy(array, makeId) {
4553
3927
  return [...new Map(array.map((e) => [makeId(e), e])).values()];
4554
3928
  }
4555
3929
  //#endregion
4556
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.3/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/data_info.js
3930
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/data_info.js
4557
3931
  /**
4558
3932
  * Type guard function that checks if the given value is a valid DataInfo.
4559
3933
  *
@@ -4742,7 +4116,7 @@ function entriesToDataInfo(dataInfoEntries) {
4742
4116
  }
4743
4117
  }
4744
4118
  //#endregion
4745
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.3/node_modules/@milaboratories/pl-model-common/dist/errors.js
4119
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/errors.js
4746
4120
  var ServiceError = class extends Error {
4747
4121
  name = "ServiceError";
4748
4122
  };
@@ -4766,7 +4140,7 @@ function ensureError(value) {
4766
4140
  return new Error(stringifyValue(value));
4767
4141
  }
4768
4142
  //#endregion
4769
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.3/node_modules/@milaboratories/pl-model-common/dist/json.js
4143
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/json.js
4770
4144
  var import_canonicalize = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
4771
4145
  module.exports = function serialize(object) {
4772
4146
  if (typeof object === "number" && isNaN(object)) throw new Error("NaN is not allowed");
@@ -4799,7 +4173,7 @@ function parseJsonSafely(value, fallback) {
4799
4173
  }
4800
4174
  }
4801
4175
  //#endregion
4802
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.3/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/spec.js
4176
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/spec.js
4803
4177
  function readMetadata(metadata, key) {
4804
4178
  return metadata?.[key];
4805
4179
  }
@@ -5091,7 +4465,7 @@ function matchAxisId(query, target) {
5091
4465
  return query.name === target.name && matchDomain$1(query.domain, target.domain) && matchDomain$1(query.contextDomain, target.contextDomain);
5092
4466
  }
5093
4467
  //#endregion
5094
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.3/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/query/utils.js
4468
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/query/utils.js
5095
4469
  const BOOLEAN_TYPES = /* @__PURE__ */ new Set([
5096
4470
  "numericComparison",
5097
4471
  "stringEquals",
@@ -5196,7 +4570,7 @@ function collectSpecQueryColumns(query) {
5196
4570
  return result;
5197
4571
  }
5198
4572
  //#endregion
5199
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.3/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/table_calculate.js
4573
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/table_calculate.js
5200
4574
  function mapPTableDef(def, cb) {
5201
4575
  return {
5202
4576
  ...def,
@@ -5239,7 +4613,7 @@ function mapJoinEntry(entry, cb) {
5239
4613
  }
5240
4614
  }
5241
4615
  //#endregion
5242
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.3/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/table_common.js
4616
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/table_common.js
5243
4617
  function getPTableColumnId(spec) {
5244
4618
  switch (spec.type) {
5245
4619
  case "axis": return {
@@ -5253,7 +4627,7 @@ function getPTableColumnId(spec) {
5253
4627
  }
5254
4628
  }
5255
4629
  //#endregion
5256
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.3/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/filtered_column.js
4630
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/filtered_column.js
5257
4631
  function stringifyColumnFilteredId(key) {
5258
4632
  return canonicalizeJson(createColumnFilteredKey(key));
5259
4633
  }
@@ -5286,7 +4660,7 @@ function applyAxisFilters(spec, axisFilters) {
5286
4660
  };
5287
4661
  }
5288
4662
  //#endregion
5289
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.3/node_modules/@milaboratories/pl-model-common/dist/pool/spec.js
4663
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/pool/spec.js
5290
4664
  function isPObjectId(value) {
5291
4665
  if (typeof value !== "string") return false;
5292
4666
  return isPObjectKey(parseJsonSafely(value));
@@ -5408,7 +4782,7 @@ function throwError(v) {
5408
4782
  else throw v;
5409
4783
  }
5410
4784
  //#endregion
5411
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.3/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/discovered_column.js
4785
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/discovered_column.js
5412
4786
  function isColumnDiscoveredKey(obj) {
5413
4787
  return typeof obj === "object" && obj !== null && "__isDiscovered" in obj;
5414
4788
  }
@@ -5638,7 +5012,7 @@ function isString(value) {
5638
5012
  return typeof value === "string";
5639
5013
  }
5640
5014
  //#endregion
5641
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.3/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/ids.js
5015
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/ids.js
5642
5016
  /**
5643
5017
  * Canonically serializes a column key to a branded string id. Accepts both
5644
5018
  * the new {@link ColumnUniversalKey} and the deprecated {@link UniversalPColumnId}
@@ -5654,6 +5028,149 @@ function parseColumnIdSafely(str, fallback = void 0) {
5654
5028
  return fallback;
5655
5029
  }
5656
5030
  }
5031
+ /** Whether `value` is any of the five key forms a {@link ColumnUniversalId} serializes. */
5032
+ function isColumnUniversalKey(value) {
5033
+ return isPObjectKey(value) || isColumnFilteredKey(value) || isColumnDiscoveredKey(value) || isColumnOverriddenKey(value);
5034
+ }
5035
+ /**
5036
+ * Take a value out of however many `JSON.stringify` passes wrapped it, or `undefined`
5037
+ * when `s` is not JSON at all.
5038
+ *
5039
+ * The one definition of "how a value can be hiding inside a string" — a block id can sit
5040
+ * under several layers of escaping, and a walk over object properties reaches none of
5041
+ * them. Callers differ in what they do at the bottom (this deliberately says nothing
5042
+ * about which values count as identifiers), but they must agree on the mechanics, or
5043
+ * "what carries a block id" ends up with two answers that drift.
5044
+ *
5045
+ * The gate is cheap and does NOT require any marker in the body: a filtered id whose
5046
+ * innermost leaf is a {@link LocalPObjectKey} carries no `__isRef`, so demanding one
5047
+ * would miss it.
5048
+ */
5049
+ function peelJsonLayers(s) {
5050
+ let current = s;
5051
+ let layers = 0;
5052
+ for (;;) {
5053
+ const c0 = current.charCodeAt(0);
5054
+ if (c0 !== 123 && c0 !== 34) return void 0;
5055
+ let parsed;
5056
+ try {
5057
+ parsed = JSON.parse(current);
5058
+ } catch {
5059
+ return;
5060
+ }
5061
+ if (isString(parsed)) {
5062
+ if (parsed.length >= current.length) return void 0;
5063
+ current = parsed;
5064
+ layers++;
5065
+ continue;
5066
+ }
5067
+ return {
5068
+ value: parsed,
5069
+ layers
5070
+ };
5071
+ }
5072
+ }
5073
+ /**
5074
+ * Rewrite every block id buried inside a column id.
5075
+ *
5076
+ * A {@link GlobalPObjectKey} leaf names its upstream by block id, and the wrapper key forms
5077
+ * nest by *string* id rather than by object — so a block id can sit under several layers of
5078
+ * JSON escaping, and `queriesQualifications` carries one in a map *key*. A caller that only
5079
+ * walks object properties never reaches any of them, which is why moving a column id between
5080
+ * projects needs this rather than a generic walk.
5081
+ *
5082
+ * Recursion re-canonicalizes bottom-up, so every level is canonical afterwards — including
5083
+ * the rebuilt `queriesQualifications`, whose keys the canonical form sorts. That is the
5084
+ * property a textual rewrite cannot have: redirecting an id that is a map key changes what
5085
+ * the sorted order should be, and only rebuilding restores it.
5086
+ *
5087
+ * Returns the input itself when no block id changed, so a caller mapping ids to themselves
5088
+ * gets its value back byte-for-byte and never re-serializes a stored id. Any `string` is
5089
+ * accepted for the same reason: a caller sweeping a params object cannot know which of its
5090
+ * strings are ids, and one that is not is returned as-is.
5091
+ *
5092
+ * @param remapBlockId old block id → new block id. Throw from it to reject an id that cannot
5093
+ * be mapped.
5094
+ */
5095
+ function remapColumnIdBlockIds(id, remapBlockId) {
5096
+ return (isString(id) ? remapIdString(id, remapBlockId) : remapKey(id, remapBlockId)) ?? id;
5097
+ }
5098
+ /**
5099
+ * The string half of {@link remapColumnIdBlockIds}. `undefined` means "nothing to change",
5100
+ * which is what keeps an unaffected id from being re-serialized.
5101
+ *
5102
+ * Escape padding is peeled and put back, so an id that reached params through an extra
5103
+ * `JSON.stringify` is rewritten in place and comes back wrapped as it was found. A string
5104
+ * that does not peel to a column key is left alone: params hold ordinary strings too.
5105
+ */
5106
+ function remapIdString(id, remapBlockId) {
5107
+ const peeled = peelJsonLayers(id);
5108
+ if (peeled === void 0 || !isColumnUniversalKey(peeled.value)) return void 0;
5109
+ const remappedKey = remapKey(peeled.value, remapBlockId);
5110
+ if (remappedKey === void 0) return void 0;
5111
+ let rebuilt = stringifyColumnId(remappedKey);
5112
+ for (let layer = 0; layer < peeled.layers; layer++) rebuilt = JSON.stringify(rebuilt);
5113
+ return rebuilt;
5114
+ }
5115
+ /** The key half of {@link remapColumnIdBlockIds}. `undefined` means "nothing to change". */
5116
+ function remapKey(key, remapBlockId) {
5117
+ if (isGlobalPObjectKey(key)) {
5118
+ const blockId = remapBlockId(key.blockId);
5119
+ return blockId === key.blockId ? void 0 : {
5120
+ ...key,
5121
+ blockId
5122
+ };
5123
+ }
5124
+ if (isLocalPObjectKey(key)) return void 0;
5125
+ if (isColumnFilteredKey(key)) {
5126
+ const source = remapIdString(key.source, remapBlockId);
5127
+ return source === void 0 ? void 0 : {
5128
+ ...key,
5129
+ source
5130
+ };
5131
+ }
5132
+ if (isColumnOverriddenKey(key)) {
5133
+ const source = remapIdString(key.source, remapBlockId);
5134
+ return source === void 0 ? void 0 : {
5135
+ ...key,
5136
+ source
5137
+ };
5138
+ }
5139
+ if (isColumnDiscoveredKey(key)) return remapDiscoveredKey(key, remapBlockId);
5140
+ throw new Error(`remapColumnIdBlockIds: unrecognized column id structure: ${JSON.stringify(key)}`);
5141
+ }
5142
+ /**
5143
+ * Discovered is the only key form carrying more than one nested id: the column it
5144
+ * discovered, one per linker hop, and one per entry in `queriesQualifications` — where the
5145
+ * id is the map key, not the value.
5146
+ */
5147
+ function remapDiscoveredKey(key, remapBlockId) {
5148
+ const column = remapIdString(key.column, remapBlockId);
5149
+ let pathChanged = false;
5150
+ const path = key.path?.map((item) => {
5151
+ const itemColumn = remapIdString(item.column, remapBlockId);
5152
+ if (itemColumn === void 0) return item;
5153
+ pathChanged = true;
5154
+ return {
5155
+ ...item,
5156
+ column: itemColumn
5157
+ };
5158
+ });
5159
+ let queriesChanged = false;
5160
+ const queriesQualifications = key.queriesQualifications && Object.fromEntries(Object.entries(key.queriesQualifications).map(([queryId, qualifications]) => {
5161
+ const remappedId = remapIdString(queryId, remapBlockId);
5162
+ if (remappedId === void 0) return [queryId, qualifications];
5163
+ queriesChanged = true;
5164
+ return [remappedId, qualifications];
5165
+ }));
5166
+ if (column === void 0 && !pathChanged && !queriesChanged) return void 0;
5167
+ return {
5168
+ ...key,
5169
+ ...column !== void 0 ? { column } : {},
5170
+ ...pathChanged ? { path } : {},
5171
+ ...queriesChanged ? { queriesQualifications } : {}
5172
+ };
5173
+ }
5657
5174
  /**
5658
5175
  * Walk a rich column id down to its terminal leaf {@link PObjectId}.
5659
5176
  */
@@ -5669,7 +5186,7 @@ function extractPObjectId(id) {
5669
5186
  throw new Error(`extractPObjectId: unrecognized column id structure: ${JSON.stringify(id)}`);
5670
5187
  }
5671
5188
  //#endregion
5672
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.3/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/overridden.js
5189
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/overridden.js
5673
5190
  function isColumnOverriddenKey(obj) {
5674
5191
  return typeof obj === "object" && obj !== null && "__isOverridden" in obj;
5675
5192
  }
@@ -5791,7 +5308,7 @@ function mergeRecord(a, b) {
5791
5308
  };
5792
5309
  }
5793
5310
  //#endregion
5794
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.3/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/anchored.js
5311
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/anchored.js
5795
5312
  function axisKey(axis) {
5796
5313
  return (0, import_canonicalize.default)(getAxisId(axis));
5797
5314
  }
@@ -6037,7 +5554,15 @@ function isAnchorAxisRef(value) {
6037
5554
  return typeof value === "object" && "anchor" in value;
6038
5555
  }
6039
5556
  //#endregion
6040
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.3/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/selectors.js
5557
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/selectors.js
5558
+ /**
5559
+ * Checks if a given value is an anchored column identifier
5560
+ * @param id - The value to check
5561
+ * @returns True if the value is an anchored column identifier, false otherwise
5562
+ */
5563
+ function isAnchoredPColumnId(id) {
5564
+ return typeof id === "object" && id !== null && "name" in id && "axes" in id;
5565
+ }
6041
5566
  /**
6042
5567
  * Determines if an axis ID matches an axis selector.
6043
5568
  *
@@ -6118,7 +5643,7 @@ function legacyColumnSelectorsToPredicate(predicateOrSelectors) {
6118
5643
  else return (spec) => isPColumnSpec(spec) && matchPColumn(spec, predicateOrSelectors);
6119
5644
  }
6120
5645
  //#endregion
6121
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.3/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/native_id.js
5646
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/native_id.js
6122
5647
  function deriveNativeId(spec) {
6123
5648
  const result = {
6124
5649
  kind: spec.kind,
@@ -6130,7 +5655,7 @@ function deriveNativeId(spec) {
6130
5655
  return (0, import_canonicalize.default)(result);
6131
5656
  }
6132
5657
  //#endregion
6133
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.3/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/linker_columns.js
5658
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/linker_columns.js
6134
5659
  var LinkerMap = class LinkerMap {
6135
5660
  /** Graph of linkers connected by axes (single or grouped by parents) */
6136
5661
  data;
@@ -6307,14 +5832,14 @@ var LinkerMap = class LinkerMap {
6307
5832
  }
6308
5833
  };
6309
5834
  //#endregion
6310
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.3/node_modules/@milaboratories/pl-model-common/dist/flags/block_flags.js
5835
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/flags/block_flags.js
6311
5836
  /**
6312
5837
  * Required PFrames version. Bump this in lockstep with the `@milaboratories/pframes-rs-*`
6313
5838
  * version in `pnpm-workspace.yaml` so blocks built against the new SDK refuse to load on
6314
5839
  * older desktop apps.
6315
5840
  */
6316
5841
  const REQUIRES_PFRAMES_VERSION = 1001031;
6317
- stringType().length(24).regex(/[ABCDEFGHIJKLMNOPQRSTUVWXYZ234567]/).brand("PlId");
5842
+ stringType().length(24).regex(/[ABCDEFGHIJKLMNOPQRSTUVWXYZ234567]/);
6318
5843
  objectType({
6319
5844
  __isRef: literalType(true).describe("Crucial marker for the block dependency tree reconstruction"),
6320
5845
  blockId: stringType().describe("Upstream block id"),
@@ -6350,7 +5875,7 @@ function withEnrichments(ref, requireEnrichments = true) {
6350
5875
  }
6351
5876
  }
6352
5877
  //#endregion
6353
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.3/node_modules/@milaboratories/pl-model-common/dist/value_or_error.js
5878
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/value_or_error.js
6354
5879
  function mapValueInVOE(voe, cb) {
6355
5880
  return voe.ok ? {
6356
5881
  ok: true,
@@ -6358,7 +5883,7 @@ function mapValueInVOE(voe, cb) {
6358
5883
  } : voe;
6359
5884
  }
6360
5885
  //#endregion
6361
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.3/node_modules/@milaboratories/pl-model-common/dist/resource_types.js
5886
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/resource_types.js
6362
5887
  /** Well-known resource type names used across the platform. */
6363
5888
  const ResourceTypeName = {
6364
5889
  StreamManager: "StreamManager",
@@ -6402,7 +5927,7 @@ const ResourceTypeName = {
6402
5927
  SharedEnvelope: "SharedEnvelope"
6403
5928
  };
6404
5929
  //#endregion
6405
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.3/node_modules/@milaboratories/pl-model-common/dist/services/service_types.js
5930
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/services/service_types.js
6406
5931
  const SERVICE_ID_PATTERN = /^[a-zA-Z][a-zA-Z0-9]*$/;
6407
5932
  const { service, isNodeService, isWasmService, isMainService, getServiceKind, getServiceModelMethods, getServiceUiMethods } = (() => {
6408
5933
  const typeMap = /* @__PURE__ */ new Map();
@@ -6441,7 +5966,7 @@ const { service, isNodeService, isWasmService, isMainService, getServiceKind, ge
6441
5966
  };
6442
5967
  })();
6443
5968
  //#endregion
6444
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.3/node_modules/@milaboratories/pl-model-common/dist/services/service_declarations.js
5969
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/services/service_declarations.js
6445
5970
  const Services = {
6446
5971
  PFrameSpec: service()({
6447
5972
  type: "wasm",
@@ -6523,271 +6048,1111 @@ const Services = {
6523
6048
  ]
6524
6049
  })
6525
6050
  };
6526
- Object.keys(Services).map((key) => `requires${key}`);
6527
- /**
6528
- * Resolve which services are required by the given feature flags.
6529
- * Accepts Record<string, unknown> so it works with both BlockCodeKnownFeatureFlags
6530
- * (from middle layer) and Zod-parsed records (from preload).
6531
- */
6532
- function resolveRequiredServices(flags) {
6533
- if (!flags) return [];
6534
- return Object.keys(Services).filter((key) => flags[`requires${key}`] === true).map((key) => Services[key]);
6535
- }
6536
- Object.fromEntries(Object.keys(Services).map((key) => [`requires${key}`, true]));
6051
+ Object.keys(Services).map((key) => `requires${key}`);
6052
+ /**
6053
+ * Resolve which services are required by the given feature flags.
6054
+ * Accepts Record<string, unknown> so it works with both BlockCodeKnownFeatureFlags
6055
+ * (from middle layer) and Zod-parsed records (from preload).
6056
+ */
6057
+ function resolveRequiredServices(flags) {
6058
+ if (!flags) return [];
6059
+ return Object.keys(Services).filter((key) => flags[`requires${key}`] === true).map((key) => Services[key]);
6060
+ }
6061
+ Object.fromEntries(Object.keys(Services).map((key) => [`requires${key}`, true]));
6062
+ //#endregion
6063
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/services/service_injectors.js
6064
+ function buildMethodMap(pick) {
6065
+ const result = {};
6066
+ for (const id of Object.values(Services)) result[id] = [...pick(id)];
6067
+ return result;
6068
+ }
6069
+ buildMethodMap(getServiceUiMethods);
6070
+ buildMethodMap(getServiceModelMethods);
6071
+ //#endregion
6072
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/columns/accessor_traversal.js
6073
+ /** Resource types that hold column collections — DFS stops here and collects. */
6074
+ const COLLECT_TYPES = [ResourceTypeName.PFrame];
6075
+ /** Resource types DFS descends through when looking for PFrames. */
6076
+ const DESCEND_TYPES = [ResourceTypeName.StdMap, ResourceTypeName.StdMapSlash];
6077
+ /**
6078
+ * Enumerate column names backing a PFrame accessor — derived from
6079
+ * `<name>.spec` field names, without resolving the spec resources.
6080
+ */
6081
+ function listColumnNames(accessor, prefix = "") {
6082
+ if (accessor.resourceType.name !== ResourceTypeName.PFrame) return [];
6083
+ const out = [];
6084
+ for (const field of accessor.listInputFields()) {
6085
+ if (!field.endsWith(".spec")) continue;
6086
+ const raw = field.slice(0, -5);
6087
+ if (!raw.startsWith(prefix)) continue;
6088
+ out.push(raw.slice(prefix.length));
6089
+ }
6090
+ return out;
6091
+ }
6092
+ /**
6093
+ * DFS over the input-field subtree of `root`. Collects nodes whose resource
6094
+ * type ∈ `collectTypes`. Descends only through `descendTypes`
6095
+ * (default: StdMap / StdMapSlash). Collected nodes are not descended into.
6096
+ *
6097
+ * Threads the field-name path from `rootPath` to each hit, so callers can
6098
+ * build canonical {@link createLocalPObjectId}s without relying on the
6099
+ * accessor itself to remember its path.
6100
+ *
6101
+ * Includes `root` itself in the walk.
6102
+ */
6103
+ function findDescendantsByType(opts) {
6104
+ const { root, rootPath, collectTypes, descendTypes = DESCEND_TYPES } = opts;
6105
+ const collectSet = new Set(collectTypes);
6106
+ const descendSet = new Set(descendTypes);
6107
+ const result = [];
6108
+ const stack = [{
6109
+ node: root,
6110
+ path: rootPath
6111
+ }];
6112
+ while (stack.length > 0) {
6113
+ const { node, path } = stack.pop();
6114
+ const typeName = node.resourceType.name;
6115
+ if (collectSet.has(typeName)) {
6116
+ result.push({
6117
+ node,
6118
+ path
6119
+ });
6120
+ continue;
6121
+ }
6122
+ if (!descendSet.has(typeName)) continue;
6123
+ const fields = node.listInputFields();
6124
+ for (let i = fields.length - 1; i >= 0; i--) {
6125
+ const child = node.traverse({
6126
+ field: fields[i],
6127
+ assertFieldType: "Input",
6128
+ ignoreError: true
6129
+ });
6130
+ if (child !== void 0) stack.push({
6131
+ node: child,
6132
+ path: [...path, fields[i]]
6133
+ });
6134
+ }
6135
+ }
6136
+ return result;
6137
+ }
6138
+ /**
6139
+ * Walk an accessor root and return one {@link LeafEntry} per discovered column.
6140
+ * Ids are {@link createLocalPObjectId}-shaped: `{resolvePath, name}`. The
6141
+ * `resolvePath` is derived from `rootPath` extended by the DFS traversal.
6142
+ */
6143
+ function indexAccessorRoot(root, rootPath) {
6144
+ const result = [];
6145
+ for (const { node, path } of findDescendantsByType({
6146
+ root,
6147
+ rootPath,
6148
+ collectTypes: COLLECT_TYPES,
6149
+ descendTypes: DESCEND_TYPES
6150
+ })) for (const name of listColumnNames(node)) result.push({
6151
+ accessor: node,
6152
+ name,
6153
+ id: createLocalPObjectId([...path], name)
6154
+ });
6155
+ return result;
6156
+ }
6157
+ /**
6158
+ * Walk one upstream-block ctx pair (`prodCtx` then `stagingCtx`) and return one
6159
+ * {@link LeafEntry} per column. First-wins dedup by name (prod precedes staging).
6160
+ * Ids are {@link createGlobalPObjectId}-shaped — `resolvePath` is not involved.
6161
+ */
6162
+ function indexPoolBlock(block) {
6163
+ const accessors = [];
6164
+ if (block.prodCtx) accessors.push(block.prodCtx);
6165
+ if (block.stagingCtx) accessors.push(block.stagingCtx);
6166
+ const result = [];
6167
+ const seen = /* @__PURE__ */ new Set();
6168
+ for (const accessor of accessors) for (const name of listColumnNames(accessor)) {
6169
+ if (seen.has(name)) continue;
6170
+ seen.add(name);
6171
+ result.push({
6172
+ accessor,
6173
+ name,
6174
+ id: createGlobalPObjectId(block.blockId, name)
6175
+ });
6176
+ }
6177
+ return result;
6178
+ }
6179
+ //#endregion
6180
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/columns/column_registry.js
6181
+ /**
6182
+ * Id-index over a set of {@link ColumnEntriesProvider}s. Sole job:
6183
+ * {@link PObjectId} → {@link LeafEntry}. Generic over the accessor flavour, so
6184
+ * the same class backs both sandbox (`TreeNodeAccessor`) and host
6185
+ * (`PlTreeNodeAccessor`) usage.
6186
+ *
6187
+ * Stateless beyond the provider list — every lookup goes through each
6188
+ * provider's `getPObjectEntries()` (cached inside the provider). Instantiate
6189
+ * directly at the call site that has the providers; there is no ambient
6190
+ * singleton.
6191
+ */
6192
+ var ColumnRegistry = class {
6193
+ providers;
6194
+ constructor(providers) {
6195
+ this.providers = providers;
6196
+ }
6197
+ /**
6198
+ * Resolve a {@link PObjectId} to its backing {@link LeafEntry}. Returns
6199
+ * `undefined` if the column is not reachable from any provider — caller
6200
+ * decides whether that's `absent` or `resolving` via {@link isFinal}.
6201
+ */
6202
+ resolve(id) {
6203
+ return this.lookupById(id);
6204
+ }
6205
+ /** Whether every indexed source has finished enumerating its columns. */
6206
+ isFinal() {
6207
+ return this.providers.every((p) => p.isFinal());
6208
+ }
6209
+ lookupById(id) {
6210
+ for (const p of this.providers) {
6211
+ const hit = p.getPObjectEntries().get(id);
6212
+ if (hit !== void 0) return hit;
6213
+ }
6214
+ }
6215
+ };
6216
+ //#endregion
6217
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/columns/dedup.js
6218
+ /**
6219
+ * Two-track dedup over an item stream keyed by `ColumnUniversalId`:
6220
+ *
6221
+ * - **Raw `PObjectId`s** are deduped by `deriveNativeId(spec)`. The same
6222
+ * physical column reached via outputs vs. result_pool has different
6223
+ * id shapes but identical nativeId — first occurrence wins so the
6224
+ * provider order (outputs before pool) decides which id is canonical.
6225
+ * - **Non-`PObjectId` ids** (e.g. `SUniversalPColumnUniversalId`,
6226
+ * `ColumnDiscoveredId`) keep raw-id dedup — they legitimately share
6227
+ * nativeId with siblings.
6228
+ *
6229
+ * When `getSpec` returns `undefined` for a `PObjectId`, falls back to raw-id
6230
+ * dedup (so an unresolvable id still survives instead of dropping silently).
6231
+ *
6232
+ * Shared by sandbox-side `extractColumns` (column_providers) and host-side
6233
+ * `ColumnsCollectionDriverImpl.getColumns` — both layers need identical
6234
+ * dedup semantics, but operate on different concrete item types (DataColumnRecipe
6235
+ * vs. raw ColumnUniversalId).
6236
+ */
6237
+ function dedupColumns(items, getId, getSpec) {
6238
+ const seenNative = /* @__PURE__ */ new Set();
6239
+ const seenId = /* @__PURE__ */ new Set();
6240
+ const out = [];
6241
+ for (const item of items) {
6242
+ const id = getId(item);
6243
+ if (seenId.has(id)) continue;
6244
+ if (isPObjectId(id)) {
6245
+ const spec = getSpec(item);
6246
+ if (spec !== void 0) {
6247
+ const nativeId = deriveNativeId(spec);
6248
+ if (seenNative.has(nativeId)) continue;
6249
+ seenNative.add(nativeId);
6250
+ }
6251
+ }
6252
+ seenId.add(id);
6253
+ out.push(item);
6254
+ }
6255
+ return out;
6256
+ }
6257
+ //#endregion
6258
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/columns/providers.js
6259
+ /**
6260
+ * Generic entries provider over a single accessor root. Walks `<root>` once
6261
+ * from the supplied `rootPath`, builds an id → {@link LeafEntry} map and
6262
+ * exposes `isFinal()` via the root's `getInputsLocked()`.
6263
+ *
6264
+ * Used directly on the host side; sandbox extends it with `getColumns()`
6265
+ * returning {@link DataColumnRecipe}s — see `AccessorColumnsProvider` in
6266
+ * `@platforma-sdk/model`.
6267
+ */
6268
+ var AccessorEntriesProvider = class {
6269
+ root;
6270
+ entries;
6271
+ constructor(root, rootPath) {
6272
+ this.root = root;
6273
+ const map = /* @__PURE__ */ new Map();
6274
+ for (const entry of indexAccessorRoot(root, rootPath)) if (!map.has(entry.id)) map.set(entry.id, entry);
6275
+ this.entries = map;
6276
+ }
6277
+ getPObjectEntries() {
6278
+ return this.entries;
6279
+ }
6280
+ isFinal() {
6281
+ return this.root.getInputsLocked();
6282
+ }
6283
+ };
6284
+ /**
6285
+ * Generic entries provider over a list of upstream-block ctx pairs.
6286
+ *
6287
+ * Per-block merge: iterate `prod` then `staging`, dedupe by name with
6288
+ * first-wins semantics (prod takes precedence).
6289
+ *
6290
+ * `isFinal()` is the AND of `getInputsLocked()` over every present ctx
6291
+ * accessor and `!prodIncomplete && !stagingIncomplete` over every block.
6292
+ */
6293
+ var ResultPoolEntriesProvider = class {
6294
+ blocks;
6295
+ cachedEntries;
6296
+ constructor(blocks) {
6297
+ this.blocks = blocks;
6298
+ }
6299
+ getPObjectEntries() {
6300
+ if (this.cachedEntries !== void 0) return this.cachedEntries;
6301
+ const map = /* @__PURE__ */ new Map();
6302
+ for (const block of this.blocks) for (const entry of indexPoolBlock(block)) if (!map.has(entry.id)) map.set(entry.id, entry);
6303
+ return this.cachedEntries = map;
6304
+ }
6305
+ isFinal() {
6306
+ for (const block of this.blocks) {
6307
+ if (block.prodIncomplete || block.stagingIncomplete) return false;
6308
+ if (block.prodCtx && !block.prodCtx.getInputsLocked()) return false;
6309
+ if (block.stagingCtx && !block.stagingCtx.getInputsLocked()) return false;
6310
+ }
6311
+ return true;
6312
+ }
6313
+ };
6314
+ //#endregion
6315
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/template/template_ref_form.js
6316
+ /**
6317
+ * Whether `value` is a reference in the readable spelling.
6318
+ *
6319
+ * Exact about its keys, because the shape lives inside params a kind owns: `{ block, name }`
6320
+ * and nothing else. A value carrying `__isRef` is a `PlRef` already and is not this — the two
6321
+ * are told apart by shape and never overlap.
6322
+ */
6323
+ function isTemplatePlRef(value) {
6324
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
6325
+ const keys = Object.keys(value);
6326
+ if (keys.length !== 2 || !keys.includes("block") || !keys.includes("name")) return false;
6327
+ const { block, name } = value;
6328
+ return typeof block === "string" && typeof name === "string";
6329
+ }
6330
+ /**
6331
+ * Expand every readable reference form in `params` into the form the system stores.
6332
+ *
6333
+ * Named for the job and not for today's only case. One readable form exists so far —
6334
+ * {@link TemplatePlRef}, the leaf reference — and the rest of the identifier system is meant to
6335
+ * follow: `TemplateCUId` / `TemplateCUKey`, readable spellings of the filtered, discovered and
6336
+ * overridden column keys, whose long forms are far worse to type than a `PlRef`'s.
6337
+ *
6338
+ * **Adding one is a recognizer plus an expander**, checked before the generic object case, the
6339
+ * way `isTemplatePlRef` / `expandTemplatePlRef` are below. Two rules a nesting form has to
6340
+ * respect, both consequences of how the stored forms are built:
6341
+ *
6342
+ * - **Expand bottom-up.** A wrapper key holds its source as a canonical *string*, not as an
6343
+ * object, so the inner reference must be expanded and serialized before the outer key can be
6344
+ * assembled. Descending after building the outer form would leave the inner spelling inside a
6345
+ * string nothing looks at again.
6346
+ * - **Canonicalize what you build.** An identifier IS its canonical string; a key assembled
6347
+ * with keys in another order is a different identifier for the same column.
6348
+ *
6349
+ * What comes out names its upstreams by template-local entry id — the same thing a `PlRef` in a
6350
+ * template file means. Turning those into the ids of real blocks is {@link relocateBlockIds},
6351
+ * which runs right after and treats an expanded reference exactly like one the file spelled out
6352
+ * in full.
6353
+ *
6354
+ * Needs nothing but the params. That is a property of the forms, not a coincidence: a readable
6355
+ * spelling carries the same information as the form it stands for, so expansion is a rewrite and
6356
+ * never a lookup. A form that needed the document to expand — a reference by position, say —
6357
+ * would have to be resolved somewhere that knows the document, and would drag that knowledge
6358
+ * into every caller of this. Keep them information-preserving.
6359
+ */
6360
+ function expandTemplateRefs(params) {
6361
+ const walk = (node) => {
6362
+ if (isTemplatePlRef(node)) return expandTemplatePlRef(node);
6363
+ if (Array.isArray(node)) return node.map(walk);
6364
+ if (typeof node === "object" && node !== null) return Object.fromEntries(Object.entries(node).map(([k, v]) => [k, walk(v)]));
6365
+ return node;
6366
+ };
6367
+ return walk(params);
6368
+ }
6369
+ /**
6370
+ * The leaf form's expander: `{ block, name }` becomes the `PlRef` it stands for.
6371
+ *
6372
+ * An id naming no entry is passed through, like a hand-written `PlRef` would be: an id naming
6373
+ * nothing and an id naming an entry created later are indistinguishable, and both are meant to
6374
+ * arrive at a block that reports itself as missing references.
6375
+ */
6376
+ function expandTemplatePlRef(ref) {
6377
+ return {
6378
+ __isRef: true,
6379
+ blockId: ref.block,
6380
+ name: ref.name
6381
+ };
6382
+ }
6383
+ //#endregion
6384
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/template/template_relocate.js
6385
+ /**
6386
+ * Point every column identifier in a block's params at the blocks of the project being built.
6387
+ *
6388
+ * The whole of what a template does about references, and it lives here — in the package the
6389
+ * block's own bundle imports — because knowing which values carry block ids is knowing the
6390
+ * reference system. The engine carrying the params neither marks them, reads them, nor
6391
+ * rewrites them: it hands the block its params and this map, and takes back what comes out.
6392
+ *
6393
+ * Params travel verbatim precisely so that this is possible. A file holds a `PlRef` as the
6394
+ * object the block stored and a column id as the canonical string the block stored, with no
6395
+ * marker of any kind, and the identifiers are found here by recognizing them — the same way
6396
+ * the project's own dependency detector finds them in live args.
6397
+ *
6398
+ * Rewriting is structural, never textual: an identifier is taken apart, its `blockId` fields
6399
+ * are replaced, and it is rebuilt canonically. That is what keeps a value that merely *looks*
6400
+ * like an id — a `domain` entry, an axis filter — from being rewritten along with it, and
6401
+ * what re-sorts a qualifications map whose keys are identifiers.
6402
+ *
6403
+ * An id the map does not mention is left as it is. That is the ordering rule doing its work:
6404
+ * a caller building the map as it creates blocks passes only the entries already created, so
6405
+ * a reference to an entry further down the file stays pointing at a block that does not
6406
+ * exist, and the applied block reports itself as missing references rather than being wired
6407
+ * to something below it.
6408
+ *
6409
+ * @param params Whatever the block projected, as the document stored it
6410
+ * @param blockIds template-local entry id → the block id that entry was given
6411
+ */
6412
+ function relocateBlockIds(params, blockIds) {
6413
+ if (blockIds.size === 0) return params;
6414
+ const remapBlockId = (blockId) => blockIds.get(blockId) ?? blockId;
6415
+ const walk = (node) => {
6416
+ if (typeof node === "string") return remapColumnIdBlockIds(node, remapBlockId);
6417
+ if (isColumnUniversalKey(node)) return remapColumnIdBlockIds(node, remapBlockId);
6418
+ if (Array.isArray(node)) return node.map(walk);
6419
+ if (typeof node === "object" && node !== null) return Object.fromEntries(Object.entries(node).map(([key, value]) => [remapColumnIdBlockIds(key, remapBlockId), walk(value)]));
6420
+ return node;
6421
+ };
6422
+ return walk(params);
6423
+ }
6424
+ //#endregion
6425
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/block_migrations.js
6426
+ /** Create a DataVersioned wrapper with correct shape */
6427
+ function makeVersionedData(version, data) {
6428
+ return {
6429
+ version,
6430
+ data
6431
+ };
6432
+ }
6433
+ /** Thrown by recover() to signal unrecoverable data. */
6434
+ var DataUnrecoverableError = class extends Error {
6435
+ name = "DataUnrecoverableError";
6436
+ constructor(dataVersion) {
6437
+ super(`Unknown version '${dataVersion}'`);
6438
+ }
6439
+ };
6440
+ function isDataUnrecoverableError(error) {
6441
+ return error instanceof Error && error.name === "DataUnrecoverableError";
6442
+ }
6443
+ /**
6444
+ * Default recover function for unknown versions.
6445
+ * Use as fallback at the end of custom recover functions.
6446
+ *
6447
+ * @example
6448
+ * .recover((version, data) => {
6449
+ * if (version === 'legacy') {
6450
+ * return transformLegacyData(data);
6451
+ * }
6452
+ * return defaultRecover(version, data);
6453
+ * })
6454
+ */
6455
+ const defaultRecover = (version, _data) => {
6456
+ throw new DataUnrecoverableError(version);
6457
+ };
6458
+ /** Symbol for internal builder creation method */
6459
+ const FROM_BUILDER = Symbol("fromBuilder");
6460
+ /**
6461
+ * Abstract base for both migration chain types.
6462
+ * Holds shared state, buildStep() helper, and init().
6463
+ * migrate() cannot be shared due to a TypeScript limitation: when the base class
6464
+ * migrate() return type is abstract, subclasses cannot narrow it without losing type safety.
6465
+ * Each subclass therefore owns its migrate() with the correct concrete return type.
6466
+ *
6467
+ * @internal
6468
+ */
6469
+ var MigrationChainBase = class {
6470
+ versionChain;
6471
+ migrationSteps;
6472
+ transferSteps;
6473
+ /** Kind reference seeded by the builder, threaded through the chain into init(). */
6474
+ kindRef;
6475
+ /** The kind's runtime params check, carried for `init()` to hand to the DataModel. */
6476
+ parseInitializationParams;
6477
+ constructor(state) {
6478
+ this.versionChain = state.versionChain;
6479
+ this.migrationSteps = state.steps;
6480
+ this.transferSteps = state.transferSteps ?? [];
6481
+ this.kindRef = state.kindRef;
6482
+ this.parseInitializationParams = state.parseInitializationParams;
6483
+ }
6484
+ /** Appends a migration step and returns the new versionChain and steps arrays. */
6485
+ buildStep(nextVersion, fn) {
6486
+ if (this.versionChain.includes(nextVersion)) throw new Error(`Duplicate version '${nextVersion}' in migration chain`);
6487
+ const step = {
6488
+ fromVersion: this.versionChain[this.versionChain.length - 1],
6489
+ toVersion: nextVersion,
6490
+ migrate: fn
6491
+ };
6492
+ return {
6493
+ versionChain: [...this.versionChain, nextVersion],
6494
+ steps: [...this.migrationSteps, step]
6495
+ };
6496
+ }
6497
+ /** Validates uniqueness and records a TransferStep. */
6498
+ buildTransfer(target, extract) {
6499
+ if (this.transferSteps.some((t) => t.pluginId === target.id)) throw new Error(`Duplicate transfer for plugin '${target.id}'`);
6500
+ const entry = {
6501
+ pluginId: target.id,
6502
+ beforeStepIndex: this.migrationSteps.length,
6503
+ extract,
6504
+ targetVersion: target.transferVersion
6505
+ };
6506
+ return { transferSteps: [...this.transferSteps, entry] };
6507
+ }
6508
+ /** Returns recover-specific fields for DataModel construction. Overridden by WithRecover. */
6509
+ recoverState() {
6510
+ return {};
6511
+ }
6512
+ /**
6513
+ * Finalize the DataModel with initial data factory.
6514
+ *
6515
+ * @param initialData - Factory function returning the initial state
6516
+ * @returns Finalized DataModel instance
6517
+ */
6518
+ init(initialData) {
6519
+ return DataModel[FROM_BUILDER]({
6520
+ versionChain: this.versionChain,
6521
+ steps: this.migrationSteps,
6522
+ transferSteps: this.transferSteps,
6523
+ initialDataFn: initialData,
6524
+ kindRef: this.kindRef,
6525
+ parseInitializationParams: this.parseInitializationParams,
6526
+ ...this.recoverState()
6527
+ });
6528
+ }
6529
+ };
6530
+ /**
6531
+ * Migration chain after recover() or upgradeLegacy() has been called.
6532
+ * Further migrate() and transfer() calls are allowed; recover() and upgradeLegacy() are not
6533
+ * (enforced by type — no such methods on this class).
6534
+ *
6535
+ * @typeParam Current - Data type at the current point in the chain
6536
+ * @typeParam Transfers - Accumulated transfer types keyed by plugin ID
6537
+ * @internal
6538
+ */
6539
+ var DataModelMigrationChainWithRecover = class DataModelMigrationChainWithRecover extends MigrationChainBase {
6540
+ recoverFn;
6541
+ recoverFromIndex;
6542
+ /** @internal */
6543
+ constructor(state) {
6544
+ super(state);
6545
+ this.recoverFn = state.recoverFn;
6546
+ this.recoverFromIndex = state.recoverFromIndex;
6547
+ }
6548
+ recoverState() {
6549
+ return {
6550
+ recoverFn: this.recoverFn,
6551
+ recoverFromIndex: this.recoverFromIndex
6552
+ };
6553
+ }
6554
+ /**
6555
+ * Add a migration step. Same semantics as on the base chain.
6556
+ * recover() and upgradeLegacy() are not available — one has already been called.
6557
+ */
6558
+ migrate(nextVersion, fn) {
6559
+ const { versionChain, steps } = this.buildStep(nextVersion, fn);
6560
+ return new DataModelMigrationChainWithRecover({
6561
+ versionChain,
6562
+ steps,
6563
+ transferSteps: this.transferSteps,
6564
+ kindRef: this.kindRef,
6565
+ parseInitializationParams: this.parseInitializationParams,
6566
+ recoverFn: this.recoverFn,
6567
+ recoverFromIndex: this.recoverFromIndex
6568
+ });
6569
+ }
6570
+ /**
6571
+ * Extract data at the current chain position for seeding a new plugin.
6572
+ * The extract function's return type must match the plugin's transfer data type.
6573
+ * Duplicate plugin IDs are rejected at both type and runtime level.
6574
+ */
6575
+ transfer(target, extract) {
6576
+ const { transferSteps } = this.buildTransfer(target, extract);
6577
+ return new DataModelMigrationChainWithRecover({
6578
+ versionChain: this.versionChain,
6579
+ steps: this.migrationSteps,
6580
+ transferSteps,
6581
+ kindRef: this.kindRef,
6582
+ parseInitializationParams: this.parseInitializationParams,
6583
+ recoverFn: this.recoverFn,
6584
+ recoverFromIndex: this.recoverFromIndex
6585
+ });
6586
+ }
6587
+ };
6588
+ /**
6589
+ * Migration chain builder.
6590
+ * Each migrate() call advances the current data type. recover() can be called once
6591
+ * at any point — it removes itself from the returned chain so it cannot be called again.
6592
+ * Duplicate version keys throw at runtime.
6593
+ *
6594
+ * @typeParam Current - Data type at the current point in the migration chain
6595
+ * @typeParam Transfers - Accumulated transfer types keyed by plugin ID
6596
+ * @internal
6597
+ */
6598
+ var DataModelMigrationChain = class DataModelMigrationChain extends MigrationChainBase {
6599
+ /** @internal */
6600
+ constructor({ versionChain, steps = [], transferSteps = [], kindRef, parseInitializationParams }) {
6601
+ super({
6602
+ versionChain,
6603
+ steps,
6604
+ transferSteps,
6605
+ kindRef,
6606
+ parseInitializationParams
6607
+ });
6608
+ }
6609
+ /**
6610
+ * Add a migration step transforming data from the current version to the next.
6611
+ *
6612
+ * @typeParam Next - Data type of the next version
6613
+ * @param nextVersion - Version key to migrate to (must be unique in the chain)
6614
+ * @param fn - Migration function
6615
+ * @returns Builder with the next version as current
6616
+ *
6617
+ * @example
6618
+ * .migrate<BlockDataV2>("v2", (v1) => ({ ...v1, labels: [] }))
6619
+ */
6620
+ migrate(nextVersion, fn) {
6621
+ const { versionChain, steps } = this.buildStep(nextVersion, fn);
6622
+ return new DataModelMigrationChain({
6623
+ versionChain,
6624
+ steps,
6625
+ transferSteps: this.transferSteps,
6626
+ kindRef: this.kindRef,
6627
+ parseInitializationParams: this.parseInitializationParams
6628
+ });
6629
+ }
6630
+ /**
6631
+ * Extract data at the current chain position for seeding a new plugin.
6632
+ * The extract function's return type must match the plugin's transfer data type.
6633
+ * Duplicate plugin IDs are rejected at both type and runtime level.
6634
+ *
6635
+ * Calling .transfer() on DataModelInitialChain returns DataModelMigrationChain,
6636
+ * which removes .upgradeLegacy() from the chain (preventing a problematic combination).
6637
+ *
6638
+ * @example
6639
+ * .from<V1>("v1")
6640
+ * .transfer(tablePlugin, (v1) => ({ state: v1.tableState }))
6641
+ * .migrate<V2>("v2", ({ tableState: _, ...rest }) => rest)
6642
+ */
6643
+ transfer(target, extract) {
6644
+ const { transferSteps } = this.buildTransfer(target, extract);
6645
+ return new DataModelMigrationChain({
6646
+ versionChain: this.versionChain,
6647
+ steps: this.migrationSteps,
6648
+ transferSteps,
6649
+ kindRef: this.kindRef,
6650
+ parseInitializationParams: this.parseInitializationParams
6651
+ });
6652
+ }
6653
+ /**
6654
+ * Set a recovery handler for unknown or legacy versions.
6655
+ *
6656
+ * The recover function is called when data has a version not in the migration chain.
6657
+ * It must return data of the type at this point in the chain (Current). Any migrate()
6658
+ * steps added after recover() will then run on the recovered data.
6659
+ *
6660
+ * Can only be called once — the returned chain has no recover() method.
6661
+ *
6662
+ * @param fn - Recovery function returning Current (the type at this chain position)
6663
+ * @returns Builder with migrate() and init() but without recover()
6664
+ *
6665
+ * @example
6666
+ * // Recover between migrations — recovered data goes through v3 migration
6667
+ * new DataModelBuilder<V1>("v1")
6668
+ * .migrate<V2>("v2", (v1) => ({ ...v1, label: "" }))
6669
+ * .recover((version, data) => {
6670
+ * if (version === 'legacy') return transformLegacy(data); // returns V2
6671
+ * return defaultRecover(version, data);
6672
+ * })
6673
+ * .migrate<V3>("v3", (v2) => ({ ...v2, description: "" }))
6674
+ * .init(() => ({ count: 0, label: "", description: "" }));
6675
+ */
6676
+ recover(fn) {
6677
+ return new DataModelMigrationChainWithRecover({
6678
+ versionChain: this.versionChain,
6679
+ steps: this.migrationSteps,
6680
+ transferSteps: this.transferSteps,
6681
+ kindRef: this.kindRef,
6682
+ parseInitializationParams: this.parseInitializationParams,
6683
+ recoverFn: fn,
6684
+ recoverFromIndex: this.migrationSteps.length
6685
+ });
6686
+ }
6687
+ };
6688
+ /**
6689
+ * Initial migration chain returned by `.from()`.
6690
+ * Extends DataModelMigrationChain with `upgradeLegacy()` — available only before
6691
+ * any `.migrate()` calls, since legacy data always arrives at the initial version.
6692
+ *
6693
+ * @typeParam Current - Data type at the initial version
6694
+ * @typeParam Transfers - Accumulated transfer types keyed by plugin ID
6695
+ * @internal
6696
+ */
6697
+ var DataModelInitialChain = class extends DataModelMigrationChain {
6698
+ /**
6699
+ * Handle legacy V1 model state ({ args, uiState }) when upgrading a block from
6700
+ * BlockModel V1 to BlockModelV3.
6701
+ *
6702
+ * When a V1 block is upgraded, its stored state `{ args, uiState }` is normalized
6703
+ * to the internal default version. This method inserts a migration step from that
6704
+ * internal version to the version specified in `.from()`, using the provided typed
6705
+ * callback to transform the legacy shape. Non-legacy data passes through unchanged.
6706
+ *
6707
+ * Must be called right after `.from()` — not available after `.migrate()` calls.
6708
+ * Any `.migrate()` steps added after `upgradeLegacy()` will run on the transformed result.
6709
+ *
6710
+ * Can only be called once — the returned chain has no upgradeLegacy() method.
6711
+ * Mutually exclusive with recover().
6712
+ *
6713
+ * @typeParam Args - Type of the legacy block args
6714
+ * @typeParam UiState - Type of the legacy block uiState
6715
+ * @param fn - Typed transform from { args, uiState } to Current
6716
+ * @returns Builder with migrate() and init() but without recover() or upgradeLegacy()
6717
+ *
6718
+ * @example
6719
+ * type OldArgs = { inputFile: string; threshold: number };
6720
+ * type OldUiState = { selectedTab: string };
6721
+ * type BlockData = { inputFile: string; threshold: number; selectedTab: string };
6722
+ *
6723
+ * const dataModel = new DataModelBuilder()
6724
+ * .from<BlockData>("v1")
6725
+ * .upgradeLegacy<OldArgs, OldUiState>(({ args, uiState }) => ({
6726
+ * inputFile: args.inputFile,
6727
+ * threshold: args.threshold,
6728
+ * selectedTab: uiState.selectedTab,
6729
+ * }))
6730
+ * .init(() => ({ inputFile: '', threshold: 0, selectedTab: 'main' }));
6731
+ */
6732
+ upgradeLegacy(fn) {
6733
+ const wrappedFn = (data) => {
6734
+ if (data !== null && typeof data === "object" && "args" in data) return fn(data);
6735
+ return data;
6736
+ };
6737
+ const step = {
6738
+ fromVersion: DATA_MODEL_LEGACY_VERSION,
6739
+ toVersion: this.versionChain[0],
6740
+ migrate: wrappedFn
6741
+ };
6742
+ return new DataModelMigrationChainWithRecover({
6743
+ versionChain: [DATA_MODEL_LEGACY_VERSION, ...this.versionChain],
6744
+ steps: [step, ...this.migrationSteps],
6745
+ kindRef: this.kindRef,
6746
+ parseInitializationParams: this.parseInitializationParams,
6747
+ transferSteps: this.transferSteps.map((t) => ({
6748
+ ...t,
6749
+ beforeStepIndex: t.beforeStepIndex + 1
6750
+ }))
6751
+ });
6752
+ }
6753
+ };
6754
+ /**
6755
+ * Builder entry point for creating DataModel with type-safe migrations.
6756
+ *
6757
+ * @example
6758
+ * // Simple (no migrations):
6759
+ * const dataModel = new DataModelBuilder()
6760
+ * .from<BlockData>("v1")
6761
+ * .init(() => ({ numbers: [] }));
6762
+ *
6763
+ * @example
6764
+ * // With migrations:
6765
+ * const dataModel = new DataModelBuilder()
6766
+ * .from<BlockDataV1>("v1")
6767
+ * .migrate<BlockDataV2>("v2", (v1) => ({ ...v1, labels: [] }))
6768
+ * .migrate<BlockDataV3>("v3", (v2) => ({ ...v2, description: '' }))
6769
+ * .init(() => ({ numbers: [], labels: [], description: '' }));
6770
+ *
6771
+ * @example
6772
+ * // With recover() between migrations — recovered data goes through remaining migrations:
6773
+ * const dataModelChain = new DataModelBuilder()
6774
+ * .from<BlockDataV1>("v1")
6775
+ * .migrate<BlockDataV2>("v2", (v1) => ({ ...v1, labels: [] }));
6776
+ *
6777
+ * // recover() placed before the v3 migration: recovered data goes through v3
6778
+ * const dataModel = dataModelChain
6779
+ * .recover((version, data) => {
6780
+ * if (version === 'legacy' && isLegacyData(data)) return transformLegacy(data); // returns V2
6781
+ * return defaultRecover(version, data);
6782
+ * })
6783
+ * .migrate<BlockDataV3>("v3", (v2) => ({ ...v2, description: '' }))
6784
+ * .init(() => ({ numbers: [], labels: [], description: '' }));
6785
+ *
6786
+ * @example
6787
+ * // With upgradeLegacy() — typed upgrade from BlockModel V1 state:
6788
+ * type OldArgs = { inputFile: string };
6789
+ * type OldUiState = { selectedTab: string };
6790
+ * type BlockData = { inputFile: string; selectedTab: string };
6791
+ *
6792
+ * const dataModel = new DataModelBuilder()
6793
+ * .from<BlockData>("v1")
6794
+ * .upgradeLegacy<OldArgs, OldUiState>(({ args, uiState }) => ({
6795
+ * inputFile: args.inputFile,
6796
+ * selectedTab: uiState.selectedTab,
6797
+ * }))
6798
+ * .init(() => ({ inputFile: '', selectedTab: 'main' }));
6799
+ */
6800
+ var DataModelBuilder = class {
6801
+ #kindRef;
6802
+ #parseInitializationParams;
6803
+ /**
6804
+ * @param opts.kind - The block kind this data model implements. Its reference
6805
+ * is captured and baked into the config so the manifest can advertise which
6806
+ * kind the block satisfies, and its `Params` type flows into `.init()`.
6807
+ * Optional during the transition window while existing V3 blocks are
6808
+ * migrated to kind-carrying builders; a kind-less builder simply carries no
6809
+ * reference and the reconciler can't project it yet. Object form mirrors
6810
+ * `BlockModelV3.create({ dataModel, kind })`.
6811
+ */
6812
+ constructor(opts) {
6813
+ this.#kindRef = opts?.kind ? formatKindRef(opts.kind) : void 0;
6814
+ this.#parseInitializationParams = opts?.kind?.parseInitializationParams;
6815
+ }
6816
+ /**
6817
+ * Start the migration chain with the given initial data type and version key.
6818
+ *
6819
+ * @typeParam T - Data type for the initial version
6820
+ * @param initialVersion - Version key string (e.g. "v1")
6821
+ * @returns Migration chain builder
6822
+ */
6823
+ from(initialVersion) {
6824
+ return new DataModelInitialChain({
6825
+ versionChain: [initialVersion],
6826
+ kindRef: this.#kindRef,
6827
+ parseInitializationParams: this.#parseInitializationParams
6828
+ });
6829
+ }
6830
+ };
6831
+ /**
6832
+ * DataModel defines the block's data structure, initial values, and migrations.
6833
+ * Used by BlockModelV3 to manage data state.
6834
+ *
6835
+ * Use `new DataModelBuilder()` to create a DataModel.
6836
+ *
6837
+ * @example
6838
+ * // With recover() between migrations:
6839
+ * // Recovered data (V2) goes through the v2→v3 migration automatically.
6840
+ * const dataModel = new DataModelBuilder()
6841
+ * .from<V1>("v1")
6842
+ * .migrate<V2>("v2", (v1) => ({ ...v1, label: "" }))
6843
+ * .recover((version, data) => {
6844
+ * if (version === "legacy") return transformLegacy(data); // returns V2
6845
+ * return defaultRecover(version, data);
6846
+ * })
6847
+ * .migrate<V3>("v3", (v2) => ({ ...v2, description: "" }))
6848
+ * .init(() => ({ count: 0, label: "", description: "" }));
6849
+ */
6850
+ var DataModel = class DataModel {
6851
+ /** Latest version key — O(1) access for the common "already current" check. */
6852
+ latestVersion;
6853
+ /** Maps each known version key to the index of the first step to run from it. O(1) lookup. */
6854
+ stepsByFromVersion;
6855
+ steps;
6856
+ transferSteps;
6857
+ initialDataFn;
6858
+ recoverFn;
6859
+ recoverFromIndex;
6860
+ /** Reference to the block kind this data model was built for, if any. */
6861
+ _kindRef;
6862
+ /** The kind's runtime params check, if it declares one. */
6863
+ _parseInitializationParams;
6864
+ constructor({ versionChain, steps, transferSteps = [], initialDataFn, kindRef, parseInitializationParams, recoverFn = defaultRecover, recoverFromIndex }) {
6865
+ if (versionChain.length === 0) throw new Error("DataModel requires at least one version key");
6866
+ this.latestVersion = versionChain[versionChain.length - 1];
6867
+ this.stepsByFromVersion = new Map(versionChain.map((v, i) => [v, i]));
6868
+ this.steps = steps;
6869
+ this.transferSteps = transferSteps;
6870
+ this.initialDataFn = initialDataFn;
6871
+ this._kindRef = kindRef;
6872
+ this._parseInitializationParams = parseInitializationParams;
6873
+ this.recoverFn = recoverFn;
6874
+ this.recoverFromIndex = recoverFromIndex ?? steps.length;
6875
+ }
6876
+ /**
6877
+ * Internal method for creating DataModel from builder.
6878
+ * Uses Symbol key to prevent external access.
6879
+ * @internal
6880
+ */
6881
+ static [FROM_BUILDER](state) {
6882
+ return new DataModel(state);
6883
+ }
6884
+ /**
6885
+ * Reference to the block kind this data model was built for, or `undefined`
6886
+ * for a kind-less builder. Used by `BlockModelV3.create` to cross-check that
6887
+ * the kind handed to the builder matches the kind handed to `create`.
6888
+ * @internal
6889
+ */
6890
+ get kindRef() {
6891
+ return this._kindRef;
6892
+ }
6893
+ /**
6894
+ * The kind's runtime params check, or `undefined` if the kind declares none (or
6895
+ * there is no kind). Read by `BlockModelV3.done()` to register the check, and
6896
+ * carried here rather than only on the model because `init` — the one place params
6897
+ * are consumed — lives on this side.
6898
+ * @internal
6899
+ */
6900
+ get templateParamsParser() {
6901
+ return this._parseInitializationParams;
6902
+ }
6903
+ /**
6904
+ * The latest (current) version key in the migration chain.
6905
+ */
6906
+ get version() {
6907
+ return this.latestVersion;
6908
+ }
6909
+ /**
6910
+ * Get a fresh copy of the initial data.
6911
+ */
6912
+ initialData() {
6913
+ return this.initialDataFn({});
6914
+ }
6915
+ /**
6916
+ * Get initial data wrapped with current version.
6917
+ * Used when creating new blocks or resetting to defaults.
6918
+ */
6919
+ getDefaultData() {
6920
+ return makeVersionedData(this.latestVersion, this.initialDataFn({}));
6921
+ }
6922
+ /**
6923
+ * Get initial data built from params, wrapped with current version.
6924
+ *
6925
+ * The counterpart of {@link getDefaultData} for a block created from a template
6926
+ * entry: the factory receives the entry's params instead of nothing. A factory
6927
+ * that ignores its argument produces the same result as `getDefaultData`, which
6928
+ * is why the two are separate methods rather than one optional argument — the
6929
+ * caller decides which contract it is asking for, and a block that cannot honour
6930
+ * params must not silently look like one that can.
6931
+ *
6932
+ * References inside `params` are already resolved to the target project's
6933
+ * concrete ids by the time they get here; the factory never sees a
6934
+ * template-local one.
6935
+ */
6936
+ getDataFromParams(params) {
6937
+ return makeVersionedData(this.latestVersion, this.initialDataFn({ params }));
6938
+ }
6939
+ recoverFrom(data, version) {
6940
+ let currentData = this.recoverFn(version, data);
6941
+ for (let i = this.recoverFromIndex; i < this.steps.length; i++) currentData = this.steps[i].migrate(currentData);
6942
+ return {
6943
+ version: this.latestVersion,
6944
+ data: currentData
6945
+ };
6946
+ }
6947
+ /**
6948
+ * Migrate versioned data from any version to the latest.
6949
+ * Collects transfer extractions at their designated chain positions.
6950
+ *
6951
+ * - If version is in chain, applies needed migrations (O(1) lookup)
6952
+ * - If version is unknown, attempts recovery; falls back to initial data
6953
+ * - If a migration step fails, throws so the caller can preserve original data
6954
+ *
6955
+ * Transfers only fire during normal step-by-step migration:
6956
+ * - Recovery path: returns empty transfers
6957
+ * - Fast-path (already at latest): returns empty transfers
6958
+ *
6959
+ * @param versioned - Data with version tag
6960
+ * @returns Migrated data at the latest version with transfer record
6961
+ * @throws If a migration step from a known version fails
6962
+ */
6963
+ migrate(versioned) {
6964
+ const { version: fromVersion, data } = versioned;
6965
+ if (fromVersion === this.latestVersion) return {
6966
+ version: this.latestVersion,
6967
+ data,
6968
+ transfers: {}
6969
+ };
6970
+ const startIndex = this.stepsByFromVersion.get(fromVersion);
6971
+ if (startIndex === void 0) try {
6972
+ return {
6973
+ ...this.recoverFrom(data, fromVersion),
6974
+ transfers: {}
6975
+ };
6976
+ } catch {
6977
+ return {
6978
+ ...this.getDefaultData(),
6979
+ transfers: {}
6980
+ };
6981
+ }
6982
+ let currentData = data;
6983
+ const transfers = {};
6984
+ for (let i = startIndex; i < this.steps.length; i++) {
6985
+ for (const t of this.transferSteps) if (t.beforeStepIndex === i) transfers[t.pluginId] = {
6986
+ version: t.targetVersion,
6987
+ data: t.extract(currentData)
6988
+ };
6989
+ currentData = this.steps[i].migrate(currentData);
6990
+ }
6991
+ for (const t of this.transferSteps) if (t.beforeStepIndex >= this.steps.length && t.beforeStepIndex >= startIndex) transfers[t.pluginId] = {
6992
+ version: t.targetVersion,
6993
+ data: t.extract(currentData)
6994
+ };
6995
+ return {
6996
+ version: this.latestVersion,
6997
+ data: currentData,
6998
+ transfers
6999
+ };
7000
+ }
7001
+ };
6537
7002
  //#endregion
6538
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.3/node_modules/@milaboratories/pl-model-common/dist/services/service_injectors.js
6539
- function buildMethodMap(pick) {
6540
- const result = {};
6541
- for (const id of Object.values(Services)) result[id] = [...pick(id)];
6542
- return result;
7003
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/internal.js
7004
+ /** Utility code helping to identify whether the code is running in actual UI environment */
7005
+ function isInUI() {
7006
+ return typeof globalThis.getPlatforma !== "undefined" || typeof globalThis.platforma !== "undefined";
6543
7007
  }
6544
- buildMethodMap(getServiceUiMethods);
6545
- buildMethodMap(getServiceModelMethods);
6546
- //#endregion
6547
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.3/node_modules/@milaboratories/pl-model-common/dist/columns/accessor_traversal.js
6548
- /** Resource types that hold column collections — DFS stops here and collects. */
6549
- const COLLECT_TYPES = [ResourceTypeName.PFrame];
6550
- /** Resource types DFS descends through when looking for PFrames. */
6551
- const DESCEND_TYPES = [ResourceTypeName.StdMap, ResourceTypeName.StdMapSlash];
6552
- /**
6553
- * Enumerate column names backing a PFrame accessor — derived from
6554
- * `<name>.spec` field names, without resolving the spec resources.
6555
- */
6556
- function listColumnNames(accessor, prefix = "") {
6557
- if (accessor.resourceType.name !== ResourceTypeName.PFrame) return [];
6558
- const out = [];
6559
- for (const field of accessor.listInputFields()) {
6560
- if (!field.endsWith(".spec")) continue;
6561
- const raw = field.slice(0, -5);
6562
- if (!raw.startsWith(prefix)) continue;
6563
- out.push(raw.slice(prefix.length));
6564
- }
6565
- return out;
7008
+ /** Utility code helping to retrieve a platforma instance form the environment */
7009
+ function getPlatformaInstance(config) {
7010
+ if (config && typeof globalThis.getPlatforma === "function") return globalThis.getPlatforma(config);
7011
+ else if (typeof globalThis.platforma !== "undefined") return globalThis.platforma;
7012
+ else throw new Error("Can't get platforma instance.");
7013
+ }
7014
+ function tryGetCfgRenderCtx() {
7015
+ if (typeof globalThis.cfgRenderCtx !== "undefined") return globalThis.cfgRenderCtx;
7016
+ else return void 0;
7017
+ }
7018
+ function getCfgRenderCtx() {
7019
+ if (typeof globalThis.cfgRenderCtx !== "undefined") return globalThis.cfgRenderCtx;
7020
+ else throw new Error("Not in config rendering context");
7021
+ }
7022
+ function tryRegisterCallback(key, callback) {
7023
+ const ctx = tryGetCfgRenderCtx();
7024
+ if (ctx === void 0) return false;
7025
+ if (key in ctx.callbackRegistry) throw new Error(`Callback with key ${key} already registered.`);
7026
+ ctx.callbackRegistry[key] = callback;
7027
+ return true;
6566
7028
  }
6567
7029
  /**
6568
- * DFS over the input-field subtree of `root`. Collects nodes whose resource
6569
- * type ∈ `collectTypes`. Descends only through `descendTypes`
6570
- * (default: StdMap / StdMapSlash). Collected nodes are not descended into.
6571
- *
6572
- * Threads the field-name path from `rootPath` to each hit, so callers can
6573
- * build canonical {@link createLocalPObjectId}s without relying on the
6574
- * accessor itself to remember its path.
7030
+ * Registers a callback, replacing any existing callback with the same key.
7031
+ * Use this for callbacks that have a default value but can be overridden.
6575
7032
  *
6576
- * Includes `root` itself in the walk.
7033
+ * @param key - The callback registry key
7034
+ * @param callback - The callback function to register
7035
+ * @returns true if registered, false if not in render context
6577
7036
  */
6578
- function findDescendantsByType(opts) {
6579
- const { root, rootPath, collectTypes, descendTypes = DESCEND_TYPES } = opts;
6580
- const collectSet = new Set(collectTypes);
6581
- const descendSet = new Set(descendTypes);
6582
- const result = [];
6583
- const stack = [{
6584
- node: root,
6585
- path: rootPath
6586
- }];
6587
- while (stack.length > 0) {
6588
- const { node, path } = stack.pop();
6589
- const typeName = node.resourceType.name;
6590
- if (collectSet.has(typeName)) {
6591
- result.push({
6592
- node,
6593
- path
6594
- });
6595
- continue;
6596
- }
6597
- if (!descendSet.has(typeName)) continue;
6598
- const fields = node.listInputFields();
6599
- for (let i = fields.length - 1; i >= 0; i--) {
6600
- const child = node.traverse({
6601
- field: fields[i],
6602
- assertFieldType: "Input",
6603
- ignoreError: true
6604
- });
6605
- if (child !== void 0) stack.push({
6606
- node: child,
6607
- path: [...path, fields[i]]
6608
- });
6609
- }
6610
- }
6611
- return result;
7037
+ function replaceCallback(key, callback) {
7038
+ const ctx = tryGetCfgRenderCtx();
7039
+ if (ctx === void 0) return false;
7040
+ ctx.callbackRegistry[key] = callback;
7041
+ return true;
6612
7042
  }
6613
- /**
6614
- * Walk an accessor root and return one {@link LeafEntry} per discovered column.
6615
- * Ids are {@link createLocalPObjectId}-shaped: `{resolvePath, name}`. The
6616
- * `resolvePath` is derived from `rootPath` extended by the DFS traversal.
6617
- */
6618
- function indexAccessorRoot(root, rootPath) {
6619
- const result = [];
6620
- for (const { node, path } of findDescendantsByType({
6621
- root,
6622
- rootPath,
6623
- collectTypes: COLLECT_TYPES,
6624
- descendTypes: DESCEND_TYPES
6625
- })) for (const name of listColumnNames(node)) result.push({
6626
- accessor: node,
6627
- name,
6628
- id: createLocalPObjectId([...path], name)
7043
+ /** Creates a ConfigRenderLambda descriptor without registering a callback. */
7044
+ function createRenderLambda(opts) {
7045
+ const { handle, ...flags } = opts;
7046
+ return {
7047
+ __renderLambda: true,
7048
+ handle,
7049
+ ...flags
7050
+ };
7051
+ }
7052
+ /** Registers a callback and returns a ConfigRenderLambda descriptor. */
7053
+ function createAndRegisterRenderLambda(opts, replace) {
7054
+ const { handle, lambda, ...flags } = opts;
7055
+ if (replace) replaceCallback(handle, lambda);
7056
+ else tryRegisterCallback(handle, lambda);
7057
+ return createRenderLambda({
7058
+ handle,
7059
+ ...flags
6629
7060
  });
6630
- return result;
6631
7061
  }
6632
- /**
6633
- * Walk one upstream-block ctx pair (`prodCtx` then `stagingCtx`) and return one
6634
- * {@link LeafEntry} per column. First-wins dedup by name (prod precedes staging).
6635
- * Ids are {@link createGlobalPObjectId}-shaped — `resolvePath` is not involved.
6636
- */
6637
- function indexPoolBlock(block) {
6638
- const accessors = [];
6639
- if (block.prodCtx) accessors.push(block.prodCtx);
6640
- if (block.stagingCtx) accessors.push(block.stagingCtx);
6641
- const result = [];
6642
- const seen = /* @__PURE__ */ new Set();
6643
- for (const accessor of accessors) for (const name of listColumnNames(accessor)) {
6644
- if (seen.has(name)) continue;
6645
- seen.add(name);
6646
- result.push({
6647
- accessor,
6648
- name,
6649
- id: createGlobalPObjectId(block.blockId, name)
6650
- });
7062
+ const futureResolves = /* @__PURE__ */ new Map();
7063
+ function registerFutureAwait(handle, onResolve) {
7064
+ if (!(handle in getCfgRenderCtx().callbackRegistry)) {
7065
+ getCfgRenderCtx().callbackRegistry[handle] = (value) => {
7066
+ for (const res of futureResolves.get(handle)) res(value);
7067
+ };
7068
+ futureResolves.set(handle, []);
6651
7069
  }
6652
- return result;
7070
+ futureResolves.get(handle).push(onResolve);
6653
7071
  }
6654
7072
  //#endregion
6655
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.3/node_modules/@milaboratories/pl-model-common/dist/columns/column_registry.js
6656
- /**
6657
- * Id-index over a set of {@link ColumnEntriesProvider}s. Sole job:
6658
- * {@link PObjectId} → {@link LeafEntry}. Generic over the accessor flavour, so
6659
- * the same class backs both sandbox (`TreeNodeAccessor`) and host
6660
- * (`PlTreeNodeAccessor`) usage.
6661
- *
6662
- * Stateless beyond the provider list — every lookup goes through each
6663
- * provider's `getPObjectEntries()` (cached inside the provider). Instantiate
6664
- * directly at the call site that has the providers; there is no ambient
6665
- * singleton.
6666
- */
6667
- var ColumnRegistry = class {
6668
- providers;
6669
- constructor(providers) {
6670
- this.providers = providers;
6671
- }
6672
- /**
6673
- * Resolve a {@link PObjectId} to its backing {@link LeafEntry}. Returns
6674
- * `undefined` if the column is not reachable from any provider — caller
6675
- * decides whether that's `absent` or `resolving` via {@link isFinal}.
6676
- */
6677
- resolve(id) {
6678
- return this.lookupById(id);
6679
- }
6680
- /** Whether every indexed source has finished enumerating its columns. */
6681
- isFinal() {
6682
- return this.providers.every((p) => p.isFinal());
6683
- }
6684
- lookupById(id) {
6685
- for (const p of this.providers) {
6686
- const hit = p.getPObjectEntries().get(id);
6687
- if (hit !== void 0) return hit;
6688
- }
6689
- }
6690
- };
6691
- //#endregion
6692
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.3/node_modules/@milaboratories/pl-model-common/dist/columns/dedup.js
7073
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/block_storage_facade.js
6693
7074
  /**
6694
- * Two-track dedup over an item stream keyed by `ColumnUniversalId`:
6695
- *
6696
- * - **Raw `PObjectId`s** are deduped by `deriveNativeId(spec)`. The same
6697
- * physical column reached via outputs vs. result_pool has different
6698
- * id shapes but identical nativeId — first occurrence wins so the
6699
- * provider order (outputs before pool) decides which id is canonical.
6700
- * - **Non-`PObjectId` ids** (e.g. `SUniversalPColumnUniversalId`,
6701
- * `ColumnDiscoveredId`) keep raw-id dedup — they legitimately share
6702
- * nativeId with siblings.
6703
- *
6704
- * When `getSpec` returns `undefined` for a `PObjectId`, falls back to raw-id
6705
- * dedup (so an unresolvable id still survives instead of dropping silently).
7075
+ * All facade callback names as constants.
7076
+ * These are the source of truth - the interface is derived from these.
6706
7077
  *
6707
- * Shared by sandbox-side `extractColumns` (column_providers) and host-side
6708
- * `ColumnsCollectionDriverImpl.getColumns` — both layers need identical
6709
- * dedup semantics, but operate on different concrete item types (ColumnLazy
6710
- * vs. raw ColumnUniversalId).
7078
+ * IMPORTANT: When adding a new callback:
7079
+ * 1. Add the constant here
7080
+ * 2. Add the callback signature to FacadeCallbackTypes below
7081
+ * 3. The BlockStorageFacade type will automatically include it
6711
7082
  */
6712
- function dedupColumns(items, getId, getSpec) {
6713
- const seenNative = /* @__PURE__ */ new Set();
6714
- const seenId = /* @__PURE__ */ new Set();
6715
- const out = [];
6716
- for (const item of items) {
6717
- const id = getId(item);
6718
- if (seenId.has(id)) continue;
6719
- if (isPObjectId(id)) {
6720
- const spec = getSpec(item);
6721
- if (spec !== void 0) {
6722
- const nativeId = deriveNativeId(spec);
6723
- if (seenNative.has(nativeId)) continue;
6724
- seenNative.add(nativeId);
6725
- }
6726
- }
6727
- seenId.add(id);
6728
- out.push(item);
6729
- }
6730
- return out;
7083
+ const BlockStorageFacadeCallbacks = {
7084
+ StorageApplyUpdate: "__pl_storage_applyUpdate",
7085
+ StorageDebugView: "__pl_storage_debugView",
7086
+ StorageMigrate: "__pl_storage_migrate",
7087
+ ArgsDerive: "__pl_args_derive",
7088
+ PrerunArgsDerive: "__pl_prerunArgs_derive",
7089
+ StorageInitial: "__pl_storage_initial",
7090
+ InitializationParamsDerive: "__pl_initializationParams_derive",
7091
+ StorageInitialFromParams: "__pl_storage_initialFromParams",
7092
+ InitializationParamsValidate: "__pl_initializationParams_validate"
7093
+ };
7094
+ /**
7095
+ * Creates a map of lambda handles from a callbacks constant object.
7096
+ * Keys are the callback string values (e.g., '__pl_storage_applyUpdate').
7097
+ */
7098
+ function createFacadeHandles(callbacks) {
7099
+ return Object.fromEntries(Object.values(callbacks).map((handle) => [handle, createRenderLambda({ handle })]));
6731
7100
  }
6732
- //#endregion
6733
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.47.3/node_modules/@milaboratories/pl-model-common/dist/columns/providers.js
6734
7101
  /**
6735
- * Generic entries provider over a single accessor root. Walks `<root>` once
6736
- * from the supplied `rootPath`, builds an id → {@link LeafEntry} map and
6737
- * exposes `isFinal()` via the root's `getInputsLocked()`.
6738
- *
6739
- * Used directly on the host side; sandbox extends it with `getColumns()`
6740
- * returning {@link ColumnLazy}s — see `AccessorColumnsProvider` in
6741
- * `@platforma-sdk/model`.
7102
+ * Lambda handles for facade callbacks.
7103
+ * Used by the middle layer to invoke callbacks via executeSingleLambda().
6742
7104
  */
6743
- var AccessorEntriesProvider = class {
6744
- root;
6745
- entries;
6746
- constructor(root, rootPath) {
6747
- this.root = root;
6748
- const map = /* @__PURE__ */ new Map();
6749
- for (const entry of indexAccessorRoot(root, rootPath)) if (!map.has(entry.id)) map.set(entry.id, entry);
6750
- this.entries = map;
6751
- }
6752
- getPObjectEntries() {
6753
- return this.entries;
6754
- }
6755
- isFinal() {
6756
- return this.root.getInputsLocked();
6757
- }
6758
- };
7105
+ const BlockStorageFacadeHandles = createFacadeHandles(BlockStorageFacadeCallbacks);
7106
+ /** Register all facade callbacks at once. Ensures all required callbacks are provided. */
7107
+ function registerFacadeCallbacks(callbacks) {
7108
+ for (const key of Object.values(BlockStorageFacadeCallbacks)) tryRegisterCallback(key, callbacks[key]);
7109
+ }
7110
+ //#endregion
7111
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/services/block_services.js
6759
7112
  /**
6760
- * Generic entries provider over a list of upstream-block ctx pairs.
6761
- *
6762
- * Per-block merge: iterate `prod` then `staging`, dedupe by name with
6763
- * first-wins semantics (prod takes precedence).
7113
+ * Services required by all V3 blocks by default.
7114
+ * Edit this when a new service should be available to all blocks.
6764
7115
  *
6765
- * `isFinal()` is the AND of `getInputsLocked()` over every present ctx
6766
- * accessor and `!prodIncomplete && !stagingIncomplete` over every block.
7116
+ * Standalone module to avoid circular dependencies between block_model.ts
7117
+ * and service type resolution.
6767
7118
  */
6768
- var ResultPoolEntriesProvider = class {
6769
- blocks;
6770
- cachedEntries;
6771
- constructor(blocks) {
6772
- this.blocks = blocks;
7119
+ const BLOCK_SERVICE_FLAGS = {
7120
+ requiresPFrameSpec: true,
7121
+ requiresPFrame: true,
7122
+ requiresDialog: true,
7123
+ requiresColumnsCollection: true
7124
+ };
7125
+ resolveRequiredServices(BLOCK_SERVICE_FLAGS);
7126
+ //#endregion
7127
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/render/future.js
7128
+ var FutureRef = class FutureRef {
7129
+ handle;
7130
+ postProcess;
7131
+ isResolved = false;
7132
+ resolvedValue;
7133
+ constructor(handle, postProcess = (v) => v) {
7134
+ this.handle = handle;
7135
+ this.postProcess = postProcess;
7136
+ registerFutureAwait(handle, (value) => {
7137
+ this.resolvedValue = postProcess(value);
7138
+ this.isResolved = true;
7139
+ });
6773
7140
  }
6774
- getPObjectEntries() {
6775
- if (this.cachedEntries !== void 0) return this.cachedEntries;
6776
- const map = /* @__PURE__ */ new Map();
6777
- for (const block of this.blocks) for (const entry of indexPoolBlock(block)) if (!map.has(entry.id)) map.set(entry.id, entry);
6778
- return this.cachedEntries = map;
7141
+ map(mapping) {
7142
+ return new FutureRef(this.handle, (v) => mapping(this.postProcess(v)));
6779
7143
  }
6780
- isFinal() {
6781
- for (const block of this.blocks) {
6782
- if (block.prodIncomplete || block.stagingIncomplete) return false;
6783
- if (block.prodCtx && !block.prodCtx.getInputsLocked()) return false;
6784
- if (block.stagingCtx && !block.stagingCtx.getInputsLocked()) return false;
6785
- }
6786
- return true;
7144
+ mapDefined(mapping) {
7145
+ return new FutureRef(this.handle, (v) => {
7146
+ const vv = this.postProcess(v);
7147
+ return vv ? mapping(vv) : void 0;
7148
+ });
7149
+ }
7150
+ toJSON() {
7151
+ return this.isResolved ? this.resolvedValue : { __awaited_futures__: [this.handle] };
6787
7152
  }
6788
7153
  };
6789
7154
  //#endregion
6790
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/render/accessor.js
7155
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/render/accessor.js
6791
7156
  function ifDef(value, cb) {
6792
7157
  return value === void 0 ? void 0 : cb(value);
6793
7158
  }
@@ -7037,11 +7402,11 @@ var TreeNodeAccessor = class TreeNodeAccessor {
7037
7402
  }
7038
7403
  };
7039
7404
  //#endregion
7040
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/render/internal.js
7405
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/render/internal.js
7041
7406
  const MainAccessorName = "main";
7042
7407
  const StagingAccessorName = "staging";
7043
7408
  //#endregion
7044
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/render/util/axis_filtering.js
7409
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/render/util/axis_filtering.js
7045
7410
  function filterDataInfoEntries(dataInfoEntries, axisFilters) {
7046
7411
  const sortedFilters = [...axisFilters].sort((a, b) => b[0] - a[0]);
7047
7412
  const { type } = dataInfoEntries;
@@ -7105,7 +7470,7 @@ function filterDataInfoEntries(dataInfoEntries, axisFilters) {
7105
7470
  }
7106
7471
  }
7107
7472
  //#endregion
7108
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/labels/linked_column_postfix.js
7473
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/labels/linked_column_postfix.js
7109
7474
  /**
7110
7475
  * Structural postfix derivation for linked columns (phase 2 of `deriveDistinctLabels`).
7111
7476
  *
@@ -7288,7 +7653,7 @@ function derivePostfixes(entries, format = defaultLinkerFormatter) {
7288
7653
  });
7289
7654
  }
7290
7655
  //#endregion
7291
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/labels/derive_distinct_labels.js
7656
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/labels/derive_distinct_labels.js
7292
7657
  const DISTANCE_PENALTY = .001;
7293
7658
  const LABEL_TYPE = "__LABEL__";
7294
7659
  const LABEL_TYPE_FULL = "__LABEL__@1";
@@ -7576,7 +7941,7 @@ function repairBareByPresence(labels, minimized, records, stats, forcedSet, forc
7576
7941
  return patched;
7577
7942
  }
7578
7943
  //#endregion
7579
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/render/util/label.js
7944
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/render/util/label.js
7580
7945
  /** @deprecated Use deriveDistinctLabels */
7581
7946
  function deriveLabels(values, getSpec, options = {}) {
7582
7947
  return deriveDistinctLabels(values.map(getSpec), options).map((label, i) => ({
@@ -7585,7 +7950,7 @@ function deriveLabels(values, getSpec, options = {}) {
7585
7950
  }));
7586
7951
  }
7587
7952
  //#endregion
7588
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/render/util/pcolumn_data.js
7953
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/render/util/pcolumn_data.js
7589
7954
  const RT_RESOURCE_MAP = "PColumnData/ResourceMap";
7590
7955
  const RT_RESOURCE_MAP_PARTITIONED = "PColumnData/Partitioned/ResourceMap";
7591
7956
  const RT_JSON_PARTITIONED = "PColumnData/JsonPartitioned";
@@ -7879,7 +8244,7 @@ function allPColumnsReady(columns) {
7879
8244
  return columns.every(isPColumnReady);
7880
8245
  }
7881
8246
  //#endregion
7882
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/render/util/column_collection.js
8247
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/render/util/column_collection.js
7883
8248
  function isPColumnValues(value) {
7884
8249
  if (!Array.isArray(value)) return false;
7885
8250
  if (value.length === 0) return true;
@@ -8157,23 +8522,7 @@ var PColumnCollection = class {
8157
8522
  }
8158
8523
  };
8159
8524
  //#endregion
8160
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/services/block_services.js
8161
- /**
8162
- * Services required by all V3 blocks by default.
8163
- * Edit this when a new service should be available to all blocks.
8164
- *
8165
- * Standalone module to avoid circular dependencies between block_model.ts
8166
- * and service type resolution.
8167
- */
8168
- const BLOCK_SERVICE_FLAGS = {
8169
- requiresPFrameSpec: true,
8170
- requiresPFrame: true,
8171
- requiresDialog: true,
8172
- requiresColumnsCollection: true
8173
- };
8174
- resolveRequiredServices(BLOCK_SERVICE_FLAGS);
8175
- //#endregion
8176
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/services/service_bridge.js
8525
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/services/service_bridge.js
8177
8526
  /**
8178
8527
  * Builds a ServiceProxy from a ServiceDispatch.
8179
8528
  * Each service method call is forwarded to dispatch.callServiceMethod.
@@ -8182,7 +8531,7 @@ function createServiceProxy(dispatch) {
8182
8531
  return ((serviceId) => Object.freeze(Object.fromEntries(dispatch.getServiceMethods(serviceId).map((method) => [method, (...args) => dispatch.callServiceMethod(serviceId, method, ...args)]))));
8183
8532
  }
8184
8533
  //#endregion
8185
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/services/get_services.js
8534
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/services/get_services.js
8186
8535
  const cachedServices = /* @__PURE__ */ new WeakMap();
8187
8536
  function getService(name, deps) {
8188
8537
  const ctx = deps?.ctx ?? getCfgRenderCtx();
@@ -8196,7 +8545,7 @@ function getService(name, deps) {
8196
8545
  })();
8197
8546
  }
8198
8547
  //#endregion
8199
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/render/util/pframe_upgraders.js
8548
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/render/util/pframe_upgraders.js
8200
8549
  function patchInSetFilters(filters) {
8201
8550
  const inSetToOrEqual = (predicate) => {
8202
8551
  if (predicate.operator !== "InSet") return predicate;
@@ -8234,7 +8583,7 @@ function patchInSetFilters(filters) {
8234
8583
  return filters.map((filter) => mapFilter(filter, inSetToOrEqual));
8235
8584
  }
8236
8585
  //#endregion
8237
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/render/api.js
8586
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/render/api.js
8238
8587
  /**
8239
8588
  * Helper function to match domain objects
8240
8589
  * @param query Optional domain to match against
@@ -8683,27 +9032,27 @@ var PluginRenderCtx = class extends RenderCtxBase {
8683
9032
  }
8684
9033
  };
8685
9034
  //#endregion
8686
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/version.js
8687
- const PlatformaSDKVersion = "1.81.1";
9035
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/plugin_model.js
9036
+ /** Internal plugin↔block handshake. `Symbol.for` (not `Symbol`) so it stays
9037
+ * identical across multiple `@platforma-sdk/model` copies in one process. */
9038
+ const CREATE_PLUGIN_MODEL = Symbol.for("@platforma-sdk/model:createPluginModel");
9039
+ //#endregion
9040
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/version.js
9041
+ const PlatformaSDKVersion = "1.83.0";
8688
9042
  //#endregion
8689
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/bconfig/types.js
9043
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/bconfig/types.js
8690
9044
  function isConfigLambda(cfgOrFh) {
8691
9045
  return cfgOrFh.__renderLambda === true;
8692
9046
  }
8693
9047
  //#endregion
8694
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/bconfig/normalization.js
9048
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/bconfig/normalization.js
8695
9049
  function downgradeCfgOrLambda(data) {
8696
9050
  if (data === void 0) return void 0;
8697
9051
  if (isConfigLambda(data)) return data.handle;
8698
9052
  return data;
8699
9053
  }
8700
9054
  //#endregion
8701
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/plugin_model.js
8702
- /** Internal plugin↔block handshake. `Symbol.for` (not `Symbol`) so it stays
8703
- * identical across multiple `@platforma-sdk/model` copies in one process. */
8704
- const CREATE_PLUGIN_MODEL = Symbol.for("@platforma-sdk/model:createPluginModel");
8705
- //#endregion
8706
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/block_storage_callbacks.js
9055
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/block_storage_callbacks.js
8707
9056
  /**
8708
9057
  * BlockStorage Callback Implementations - wired to facade callbacks in BlockModelV3.done().
8709
9058
  *
@@ -8823,7 +9172,16 @@ function migrateStorage(currentStorageJson, hooks) {
8823
9172
  * @throws If initialDataFn or createPluginData throws
8824
9173
  */
8825
9174
  function createInitialStorage(hooks) {
8826
- const blockDefault = hooks.getDefaultBlockData();
9175
+ return assembleStorage(hooks.getDefaultBlockData(), hooks);
9176
+ }
9177
+ /**
9178
+ * Wraps freshly created block data and freshly created plugin data into storage.
9179
+ *
9180
+ * Shared by the two ways a block's first storage comes into being — from defaults
9181
+ * and from template params. Only the block's own data differs between them:
9182
+ * plugins have no params channel, so they are always created at their defaults.
9183
+ */
9184
+ function assembleStorage(blockData, hooks) {
8827
9185
  const pluginRegistry = hooks.getPluginRegistry();
8828
9186
  const plugins = {};
8829
9187
  for (const handle of Object.keys(pluginRegistry)) {
@@ -8835,52 +9193,220 @@ function createInitialStorage(hooks) {
8835
9193
  }
8836
9194
  return stringifyJson({
8837
9195
  [BLOCK_STORAGE_KEY]: "v1",
8838
- __dataVersion: blockDefault.version,
8839
- __data: blockDefault.data,
9196
+ __dataVersion: blockData.version,
9197
+ __data: blockData.data,
8840
9198
  __pluginRegistry: pluginRegistry,
8841
9199
  __plugins: plugins
8842
9200
  });
8843
9201
  }
8844
9202
  /**
9203
+ * Check params against their kind's declared shape.
9204
+ *
9205
+ * The kind owns this rather than the block because the params contract belongs to the
9206
+ * kind: many block versions implement one kind, and a per-block check would let them
9207
+ * drift from each other and from the type.
9208
+ *
9209
+ * A parser rejects by throwing and accepts by returning the params to use, so its
9210
+ * output — not the input — is what flows onward. That is what lets a kind strip keys
9211
+ * it does not declare, which is the difference between a typo being ignored and a typo
9212
+ * being reported.
9213
+ *
9214
+ * Every kind declares a parser, so every set of params that reaches here is checked;
9215
+ * there is no pass-through path.
9216
+ *
9217
+ * @param value The params to check, references already in live form
9218
+ * @param parseInitializationParams The kind's parser
9219
+ */
9220
+ function validateTemplateParams(value, parseInitializationParams) {
9221
+ try {
9222
+ return { value: parseInitializationParams(value) };
9223
+ } catch (e) {
9224
+ return { error: `params do not match this block's kind: ${describeRejection(e)}` };
9225
+ }
9226
+ }
9227
+ /**
9228
+ * Render whatever a parser threw as one readable line.
9229
+ *
9230
+ * An error carrying an `issues` array is unpacked rather than printed: that is the
9231
+ * shape zod (and several others) use, and its `message` is the whole issue list as
9232
+ * JSON — technically complete and unreadable in a dialog. Duck-typed on purpose, since
9233
+ * this package prescribes no schema library and takes no dependency on one; anything
9234
+ * else falls back to its own message.
9235
+ */
9236
+ function describeRejection(e) {
9237
+ const issues = e.issues;
9238
+ if (!Array.isArray(issues) || issues.length === 0) return messageOf(e);
9239
+ return issues.map((issue) => {
9240
+ const { path, message } = issue;
9241
+ const what = typeof message === "string" ? message : "is invalid";
9242
+ const where = Array.isArray(path) ? formatPath(path) : "";
9243
+ return where === "" ? what : `${where}: ${what}`;
9244
+ }).join("; ");
9245
+ }
9246
+ /** `["numbers", 0]` → `numbers[0]` — how the params are written, not how they parse. */
9247
+ function formatPath(path) {
9248
+ return path.reduce((acc, segment) => {
9249
+ if (typeof segment === "number") return `${acc}[${segment}]`;
9250
+ return acc === "" ? String(segment) : `${acc}.${String(segment)}`;
9251
+ }, "");
9252
+ }
9253
+ /**
9254
+ * Check params that crossed into the model VM as text.
9255
+ *
9256
+ * The pre-flight entry point: a caller asks this before creating anything, once per
9257
+ * template entry, so params a kind rejects are reported while there is still no
9258
+ * project to half-build.
9259
+ *
9260
+ * The readable reference spelling is expanded here too, so what the kind checks is the shape it
9261
+ * declared. The ids it sees are the file's own — no block exists yet — which is why a kind must
9262
+ * not read meaning into a specific id.
9263
+ *
9264
+ * @param paramsJson The entry's params as JSON string
9265
+ * @param parseInitializationParams The kind's parser
9266
+ */
9267
+ function validateTemplateParamsJson(paramsJson, parseInitializationParams) {
9268
+ let params;
9269
+ try {
9270
+ params = JSON.parse(paramsJson);
9271
+ } catch (e) {
9272
+ return { error: `params are not valid JSON: ${messageOf(e)}` };
9273
+ }
9274
+ const result = validateTemplateParams(expandTemplateRefs(params), parseInitializationParams);
9275
+ if (result.error !== void 0) return { error: result.error };
9276
+ return {};
9277
+ }
9278
+ function messageOf(e) {
9279
+ return e instanceof Error ? e.message : String(e);
9280
+ }
9281
+ /**
9282
+ * Creates complete initial storage for a block being created from template params.
9283
+ *
9284
+ * The inverse of {@link deriveTemplateParamsFromStorage}: that projects storage
9285
+ * into params, this builds storage from them. The params are handed to the block's
9286
+ * init factory, whose output is versioned and wrapped exactly as
9287
+ * {@link createInitialStorage} wraps the defaults — so a block created from a
9288
+ * template is indistinguishable from one created in the UI and then edited.
9289
+ *
9290
+ * **This is where a template's references become the block's own**, and it is the only place in
9291
+ * a template's life where a reference is recognized at all. Params travel from the file
9292
+ * untouched — the engine carrying them neither marks a reference nor reads one, because
9293
+ * recognizing one means knowing the reference system, and that knowledge is here.
9294
+ *
9295
+ * Two things happen, in this order. The readable spelling a person may have written
9296
+ * (`{ block, name }`) is expanded into the `PlRef` it stands for. Then every reference naming
9297
+ * an entry that has a block is repointed at it: `blockIds` maps each template-local entry id to
9298
+ * the block id it was given, and an id it does not name is left alone, which is how a reference
9299
+ * to an entry created later ends up naming nothing rather than naming the wrong block.
9300
+ *
9301
+ * Relocation happens before the kind's parser and before the factory, so both see the ids the
9302
+ * block will actually hold. It is one step of this function rather than a callback of its own
9303
+ * precisely because nothing else wants its result: every VM call re-instantiates the runtime
9304
+ * and re-evaluates the whole model bundle, so a separate call would parse the block twice per
9305
+ * entry to produce a value only the next line reads.
9306
+ *
9307
+ * Params arrive as JSON text because this runs across the model-VM boundary, where
9308
+ * only strings pass. Anything the factory rejects is returned as an error rather
9309
+ * than thrown: applying a hand-written template is expected to surface bad params,
9310
+ * and the applier reports every entry's problem in one pass.
9311
+ *
9312
+ * @param paramsJson - The entry's params as JSON string, exactly as the file held them
9313
+ * @param blockIdsJson - template-local entry id → assigned block id, as a JSON object
9314
+ * @param hooks - The block's init factory plus plugin creation
9315
+ * @returns The storage to write, or why the params could not produce any
9316
+ */
9317
+ function createInitialStorageFromParams(paramsJson, blockIdsJson, hooks) {
9318
+ let params;
9319
+ try {
9320
+ params = JSON.parse(paramsJson);
9321
+ } catch (e) {
9322
+ return { error: `params are not valid JSON: ${messageOf(e)}` };
9323
+ }
9324
+ let blockIds;
9325
+ try {
9326
+ blockIds = new Map(Object.entries(JSON.parse(blockIdsJson)));
9327
+ } catch (e) {
9328
+ return { error: `this block was not told which blocks the template's references should point at (${messageOf(e)}). The application applying the template is older than the block; rebuild or update it.` };
9329
+ }
9330
+ try {
9331
+ params = relocateBlockIds(expandTemplateRefs(params), blockIds);
9332
+ } catch (e) {
9333
+ return { error: `this entry's references could not be relocated: ${messageOf(e)}` };
9334
+ }
9335
+ const checked = validateTemplateParams(params, hooks.parseInitializationParams);
9336
+ if (checked.error !== void 0) return { error: checked.error };
9337
+ try {
9338
+ return { storageJson: assembleStorage(hooks.getBlockDataFromParams(checked.value), hooks) };
9339
+ } catch (e) {
9340
+ return { error: `init() threw on the given params: ${messageOf(e)}` };
9341
+ }
9342
+ }
9343
+ /**
8845
9344
  * Derives args from storage using the provided args function.
8846
9345
  * This extracts data from storage and passes it to the block's args() function.
8847
9346
  *
8848
9347
  * @param storageJson - Storage as JSON string
8849
- * @param argsFunction - The block's args derivation function
9348
+ * @param deriveArgs - The block's args derivation function
8850
9349
  * @returns ArgsDeriveResult with derived args or error
8851
9350
  */
8852
- function deriveArgsFromStorage(storageJson, argsFunction) {
9351
+ function deriveArgsFromStorage(storageJson, deriveArgs) {
8853
9352
  const { data } = normalizeStorage(storageJson);
8854
9353
  try {
8855
- return { value: argsFunction(data) };
9354
+ return { value: deriveArgs(data) };
8856
9355
  } catch (e) {
8857
9356
  return { error: `args() threw: ${e instanceof Error ? e.message : String(e)}` };
8858
9357
  }
8859
9358
  }
8860
9359
  /**
8861
9360
  * Derives prerunArgs from storage.
8862
- * Uses prerunArgsFunction if provided, otherwise falls back to argsFunction.
9361
+ * Uses derivePrerunArgs if provided, otherwise falls back to deriveArgs.
8863
9362
  *
8864
9363
  * @param storageJson - Storage as JSON string
8865
- * @param argsFunction - The block's args derivation function (fallback)
8866
- * @param prerunArgsFunction - Optional prerun args derivation function
9364
+ * @param deriveArgs - The block's args derivation function (fallback)
9365
+ * @param derivePrerunArgs - Optional prerun args derivation function
8867
9366
  * @returns ArgsDeriveResult with derived prerunArgs or error
8868
9367
  */
8869
- function derivePrerunArgsFromStorage(storageJson, argsFunction, prerunArgsFunction) {
9368
+ function derivePrerunArgsFromStorage(storageJson, deriveArgs, derivePrerunArgs) {
8870
9369
  const { data } = normalizeStorage(storageJson);
8871
- if (prerunArgsFunction) try {
8872
- return { value: prerunArgsFunction(data) };
9370
+ if (derivePrerunArgs) try {
9371
+ return { value: derivePrerunArgs(data) };
8873
9372
  } catch (e) {
8874
9373
  return { error: `prerunArgs() threw: ${e instanceof Error ? e.message : String(e)}` };
8875
9374
  }
8876
9375
  try {
8877
- return { value: argsFunction(data) };
9376
+ return { value: deriveArgs(data) };
8878
9377
  } catch (e) {
8879
9378
  return { error: `args() threw (fallback): ${e instanceof Error ? e.message : String(e)}` };
8880
9379
  }
8881
9380
  }
9381
+ /**
9382
+ * Derives this block's template-entry params from storage.
9383
+ *
9384
+ * The inverse of the data model's `init`: `init` turns `params` into data, this
9385
+ * turns data back into the params that would recreate it.
9386
+ *
9387
+ * The lambda returns ordinary live params — references as `PlRef`s, column identifiers as they
9388
+ * are stored — and that is exactly what gets written. Nothing is marked, normalized or
9389
+ * rewritten on the way out: a template holds what the block holds. Repointing those references
9390
+ * at another project is the business of {@link createInitialStorageFromParams}, on the way back
9391
+ * in, where the ids to point at are known.
9392
+ *
9393
+ * Every block declares the lambda, so every export produces params; a block with
9394
+ * nothing worth restoring returns `{}` rather than declining.
9395
+ *
9396
+ * @param storageJson - Storage as JSON string
9397
+ * @param deriveTemplateParams - The block's templateParams lambda
9398
+ * @returns ArgsDeriveResult holding the params exactly as the block projected them
9399
+ */
9400
+ function deriveTemplateParamsFromStorage(storageJson, deriveTemplateParams) {
9401
+ const { data } = normalizeStorage(storageJson);
9402
+ try {
9403
+ return { value: deriveTemplateParams(data) };
9404
+ } catch (e) {
9405
+ return { error: `templateParams() threw: ${e instanceof Error ? e.message : String(e)}` };
9406
+ }
9407
+ }
8882
9408
  //#endregion
8883
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/block_model.js
9409
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/block_model.js
8884
9410
  /**
8885
9411
  * Merges two feature flag objects with type-aware logic:
8886
9412
  * - `supports*` (boolean): OR — `true` if either side is `true`
@@ -8917,24 +9443,33 @@ var BlockModelV3 = class BlockModelV3 {
8917
9443
  /** @deprecated Use FEATURE_FLAGS */
8918
9444
  static INITIAL_BLOCK_FEATURE_FLAGS = BlockModelV3.FEATURE_FLAGS;
8919
9445
  /**
8920
- * Creates a new BlockModelV3 builder with the specified data model.
9446
+ * Creates a new BlockModelV3 builder bound to a data model and a block kind.
9447
+ *
9448
+ * The `kind` argument is cross-checked against the kind handed to the
9449
+ * builder: its `Params` type must match at compile time (via
9450
+ * `BlockKind<Params>`), and its reference value must match at runtime. The
9451
+ * reference is baked into the config so the published manifest can advertise
9452
+ * which kind the block implements.
8921
9453
  *
8922
9454
  * @example
8923
- * const dataModel = new DataModelBuilder()
9455
+ * const dataModel = new DataModelBuilder({ kind })
8924
9456
  * .from<BlockData>("v1")
8925
- * .init(() => ({ numbers: [], labels: [] }));
9457
+ * .init(({ params }) => params ?? { numbers: [], labels: [] });
8926
9458
  *
8927
- * BlockModelV3.create(dataModel)
9459
+ * BlockModelV3.create({ dataModel, kind })
8928
9460
  * .args((data) => ({ numbers: data.numbers }))
8929
9461
  * .sections(() => [{ type: 'link', href: '/', label: 'Main' }])
8930
9462
  * .done();
8931
- *
8932
- * @param dataModel The data model that defines initial data and migrations
8933
9463
  */
8934
- static create(dataModel) {
9464
+ static create(args) {
9465
+ const { dataModel, kind } = args;
9466
+ const kindRef = formatKindRef(kind);
9467
+ if (dataModel.kindRef && dataModel.kindRef !== kindRef) throw new Error(`Block kind mismatch: data model built for '${dataModel.kindRef}' but create() got '${kindRef}'`);
8935
9468
  return new BlockModelV3({
8936
9469
  renderingMode: "Heavy",
8937
9470
  dataModel,
9471
+ kind: kindRef,
9472
+ parseInitializationParams: kind.parseInitializationParams,
8938
9473
  outputs: {},
8939
9474
  sections: createAndRegisterRenderLambda({
8940
9475
  handle: "sections",
@@ -8945,8 +9480,9 @@ var BlockModelV3 = class BlockModelV3 {
8945
9480
  tags: void 0,
8946
9481
  enrichmentTargets: void 0,
8947
9482
  featureFlags: { ...BlockModelV3.FEATURE_FLAGS },
8948
- argsFunction: void 0,
8949
- prerunArgsFunction: void 0,
9483
+ deriveArgs: void 0,
9484
+ derivePrerunArgs: void 0,
9485
+ deriveTemplateParams: void 0,
8950
9486
  plugins: {}
8951
9487
  });
8952
9488
  }
@@ -8987,7 +9523,7 @@ var BlockModelV3 = class BlockModelV3 {
8987
9523
  args(lambda) {
8988
9524
  return new BlockModelV3({
8989
9525
  ...this.config,
8990
- argsFunction: lambda
9526
+ deriveArgs: lambda
8991
9527
  });
8992
9528
  }
8993
9529
  /**
@@ -9013,7 +9549,41 @@ var BlockModelV3 = class BlockModelV3 {
9013
9549
  prerunArgs(fn) {
9014
9550
  return new BlockModelV3({
9015
9551
  ...this.config,
9016
- prerunArgsFunction: fn
9552
+ derivePrerunArgs: fn
9553
+ });
9554
+ }
9555
+ /**
9556
+ * Sets the function that projects block data back to this kind's params, for
9557
+ * exporting the project as a template.
9558
+ *
9559
+ * The inverse of the data model's `init`: `init` builds data from `params`, this
9560
+ * recovers the `params` that would rebuild the current data. Return only params
9561
+ * — runtime and derived state is dropped, and the exporter supplies the rest of
9562
+ * the entry (`id`, `kind`), which this lambda cannot set.
9563
+ *
9564
+ * References are returned as ordinary `PlRef`s; the SDK rewrites them into
9565
+ * template-local form on the way out, so a block never deals with the file
9566
+ * representation.
9567
+ *
9568
+ * Required: `done()` throws without it. A block whose state cannot be reduced to
9569
+ * params returns `{}` and says so explicitly, rather than exporting an entry with
9570
+ * no params that silently applies as a default-initialized block.
9571
+ *
9572
+ * The return type is the kind's `Params`, so a block whose projection drifts
9573
+ * from its own init contract fails to compile. Available only on a
9574
+ * kind-carrying model — `create(dataModel)` without a kind leaves `Params` as
9575
+ * `unknown` and this method cannot be type-checked against anything.
9576
+ *
9577
+ * @example
9578
+ * BlockModelV3.create({ dataModel, kind })
9579
+ * .args((data) => ({ numbers: data.numbers }))
9580
+ * .templateParams((data) => ({ sources: data.sources }))
9581
+ * .done();
9582
+ */
9583
+ templateParams(fn) {
9584
+ return new BlockModelV3({
9585
+ ...this.config,
9586
+ deriveTemplateParams: fn
9017
9587
  });
9018
9588
  }
9019
9589
  /** Sets the lambda to generate list of sections in the left block overviews panel. */
@@ -9105,13 +9675,14 @@ var BlockModelV3 = class BlockModelV3 {
9105
9675
  * before calling `.done()`.
9106
9676
  */
9107
9677
  done(..._) {
9108
- if (this.config.argsFunction === void 0) throw new Error("Args rendering function not set.");
9678
+ if (this.config.deriveArgs === void 0) throw new Error("Args rendering function not set.");
9679
+ if (this.config.deriveTemplateParams === void 0) throw new Error("templateParams() not set. Every block must project its state back to its kind's params, so a project can be exported as a template and re-applied; a block whose state carries nothing worth restoring returns {}.");
9109
9680
  const apiVersion = 3;
9110
9681
  const { plugins } = this.config;
9111
9682
  const pluginRegistry = {};
9112
9683
  const pluginHandles = Object.keys(plugins);
9113
9684
  for (const handle of pluginHandles) pluginRegistry[handle] = plugins[handle].model.name;
9114
- const { dataModel, argsFunction, prerunArgsFunction } = this.config;
9685
+ const { dataModel, deriveArgs, derivePrerunArgs, deriveTemplateParams, parseInitializationParams } = this.config;
9115
9686
  function getPlugin(handle) {
9116
9687
  const plugin = plugins[handle];
9117
9688
  if (!plugin) throw new Error(`Plugin model not found for '${handle}'`);
@@ -9134,8 +9705,16 @@ var BlockModelV3 = class BlockModelV3 {
9134
9705
  getPluginRegistry: () => pluginRegistry,
9135
9706
  createPluginData: (handle) => getPlugin(handle).model.getDefaultData()
9136
9707
  }),
9137
- [BlockStorageFacadeCallbacks.ArgsDerive]: (storageJson) => deriveArgsFromStorage(storageJson, argsFunction),
9138
- [BlockStorageFacadeCallbacks.PrerunArgsDerive]: (storageJson) => derivePrerunArgsFromStorage(storageJson, argsFunction, prerunArgsFunction)
9708
+ [BlockStorageFacadeCallbacks.ArgsDerive]: (storageJson) => deriveArgsFromStorage(storageJson, deriveArgs),
9709
+ [BlockStorageFacadeCallbacks.PrerunArgsDerive]: (storageJson) => derivePrerunArgsFromStorage(storageJson, deriveArgs, derivePrerunArgs),
9710
+ [BlockStorageFacadeCallbacks.InitializationParamsDerive]: (storageJson) => deriveTemplateParamsFromStorage(storageJson, deriveTemplateParams),
9711
+ [BlockStorageFacadeCallbacks.StorageInitialFromParams]: (paramsJson, blockIdsJson) => createInitialStorageFromParams(paramsJson, blockIdsJson, {
9712
+ getBlockDataFromParams: (params) => dataModel.getDataFromParams(params),
9713
+ getPluginRegistry: () => pluginRegistry,
9714
+ createPluginData: (handle) => getPlugin(handle).model.getDefaultData(),
9715
+ parseInitializationParams
9716
+ }),
9717
+ [BlockStorageFacadeCallbacks.InitializationParamsValidate]: (paramsJson) => validateTemplateParamsJson(paramsJson, parseInitializationParams)
9139
9718
  });
9140
9719
  const pluginOutputs = {};
9141
9720
  for (const handle of pluginHandles) {
@@ -9172,6 +9751,7 @@ var BlockModelV3 = class BlockModelV3 {
9172
9751
  featureFlags: this.config.featureFlags,
9173
9752
  blockLifecycleCallbacks: { ...BlockStorageFacadeHandles }
9174
9753
  },
9754
+ kind: this.config.kind,
9175
9755
  sdkVersion: PlatformaSDKVersion,
9176
9756
  renderingMode: this.config.renderingMode,
9177
9757
  sections: this.config.sections,
@@ -9192,7 +9772,7 @@ var BlockModelV3 = class BlockModelV3 {
9192
9772
  }
9193
9773
  };
9194
9774
  //#endregion
9195
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/pframe_utils/axes.js
9775
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/pframe_utils/axes.js
9196
9776
  /** Create id for column copy with added keys in axes domains */
9197
9777
  const colId = (id, domains, contextDomains) => {
9198
9778
  let wid = id.toString();
@@ -9298,7 +9878,7 @@ function getAdditionalColumnsForColumn(blockAxes, column) {
9298
9878
  })];
9299
9879
  }
9300
9880
  //#endregion
9301
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/columns/column_recipes/leaf_rebrand.js
9881
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/columns/column_recipes/leaf_rebrand.js
9302
9882
  /**
9303
9883
  * Replace every column leaf whose id equals `fromId` with `toId`, leaving
9304
9884
  * other column refs (linkers, sub-anchors) intact. Wrapper recipes
@@ -9966,7 +10546,7 @@ var U = class d {
9966
10546
  }
9967
10547
  };
9968
10548
  //#endregion
9969
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/columns/column_providers/providers.js
10549
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/columns/column_providers/providers.js
9970
10550
  /**
9971
10551
  * Unified memoised factory dispatching to the right provider flavour by the
9972
10552
  * source shape:
@@ -10055,7 +10635,7 @@ function hashRawPool(rawPool) {
10055
10635
  return rawPool.map((b) => `${b.blockId}\x1f${b.prodCtx ?? ""}\x1f${b.stagingCtx ?? ""}\x1f${b.prodIncomplete ? 1 : 0}\x1f${b.stagingIncomplete ? 1 : 0}`).join("");
10056
10636
  }
10057
10637
  //#endregion
10058
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/columns/column_providers/index.js
10638
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/columns/column_providers/index.js
10059
10639
  /**
10060
10640
  * Build the default set of ColumnsProviders for the ambient render ctx:
10061
10641
  * - `AccessorColumnsProvider` over `outputs` (if present)
@@ -10090,7 +10670,7 @@ function isColumnProvider(source) {
10090
10670
  return typeof p.getColumns === "function" && typeof p.isFinal === "function";
10091
10671
  }
10092
10672
  //#endregion
10093
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/columns/data_column.js
10673
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/columns/data_column.js
10094
10674
  /**
10095
10675
  * Thrown by leaf-recipe factories when the requested column is provably
10096
10676
  * absent in the active render ctx — i.e. every relevant accessor reports
@@ -10330,7 +10910,7 @@ function memoizeByEntry(fn) {
10330
10910
  };
10331
10911
  }
10332
10912
  //#endregion
10333
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/columns/column_recipes/column_overrided_recipe.js
10913
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/columns/column_recipes/column_overrided_recipe.js
10334
10914
  /**
10335
10915
  * Recipe wrapper that overlays {@link SpecOverrides} on top of any other
10336
10916
  * recipe. The id is `ColumnOverriddenKey { source: inner.id, specOverrides }`.
@@ -10468,7 +11048,7 @@ var DataColumnOverriddenRecipe = class extends ColumnOverriddenRecipe {
10468
11048
  }
10469
11049
  };
10470
11050
  //#endregion
10471
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/columns/column_recipes/column_filtered_recipe.js
11051
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/columns/column_recipes/column_filtered_recipe.js
10472
11052
  /**
10473
11053
  * Recipe wrapper that fixes the values of selected axes of an inner recipe
10474
11054
  * (axis slicing). The id is `FilteredPColumnId { source: inner.id,
@@ -10594,7 +11174,7 @@ function toAxisSelector(axis) {
10594
11174
  return selector;
10595
11175
  }
10596
11176
  //#endregion
10597
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/columns/column_recipes/index.js
11177
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/columns/column_recipes/index.js
10598
11178
  /**
10599
11179
  * Build a `ColumnRecipe` from a stringified id. Dispatches to the matching
10600
11180
  * concrete recipe variant based on the id's encoding and recurses on
@@ -10645,7 +11225,7 @@ function ColumnRecipeGetStatus(id, opts = {}) {
10645
11225
  }
10646
11226
  const ColumnRecipe = Object.assign(ColumnRecipeBuild, { getStatus: ColumnRecipeGetStatus });
10647
11227
  //#endregion
10648
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/columns/column_recipes/column_discovered_recipe.js
11228
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/columns/column_recipes/column_discovered_recipe.js
10649
11229
  /**
10650
11230
  * Recipe for columns identified by a {@link ColumnDiscoveredKey}: a base
10651
11231
  * column + a `path` of linkers + qualifications.
@@ -10816,7 +11396,7 @@ function referencedUniIdsOf(key) {
10816
11396
  return /* @__PURE__ */ new Set([key.column, ...(key.path ?? []).map((item) => item.column)]);
10817
11397
  }
10818
11398
  //#endregion
10819
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/columns/column.js
11399
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/columns/column.js
10820
11400
  /**
10821
11401
  * Unified entry point — routes between the two top-level dispatchers:
10822
11402
  * - string id (`PObjectId` / `ColumnUniversalId`) → {@link ColumnRecipe}
@@ -10830,7 +11410,7 @@ function Column(source, opts) {
10830
11410
  return DataColumn(source, opts);
10831
11411
  }
10832
11412
  //#endregion
10833
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/columns/columns_collection.js
11413
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/columns/columns_collection.js
10834
11414
  /**
10835
11415
  * Build a {@link ColumnsCollection} from sandbox-side source descriptors.
10836
11416
  * Resolves the `columnsCollection` driver (either from `deps.driver` or via
@@ -10939,7 +11519,7 @@ function defaultCtxSources(ctx) {
10939
11519
  return [...currentBlockSources(ctx), { kind: "result_pool" }];
10940
11520
  }
10941
11521
  //#endregion
10942
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/columns/utils.js
11522
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/columns/utils.js
10943
11523
  /**
10944
11524
  * PObjectIds of every non-hit column referenced by `recipe.getQuery()`,
10945
11525
  * deduped in traversal order. The hit column is
@@ -11070,7 +11650,7 @@ function hasSingleDataColumn(recipe) {
11070
11650
  return recipe.getReferencedIds().length === 1;
11071
11651
  }
11072
11652
  //#endregion
11073
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/pframe_utils/columns.js
11653
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/pframe_utils/columns.js
11074
11654
  function getAllRelatedColumns(ctx, predicate) {
11075
11655
  const columns = new PColumnCollection();
11076
11656
  columns.addColumnProvider(ctx.resultPool);
@@ -11146,7 +11726,7 @@ function discoverIntegrableColumnIds(ctx, rootColumns) {
11146
11726
  }
11147
11727
  }
11148
11728
  //#endregion
11149
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/components/PFrameForGraphs.js
11729
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/components/PFrameForGraphs.js
11150
11730
  function isHiddenFromGraphColumn(column) {
11151
11731
  return !!readAnnotationJson(column, Annotation.HideDataFromGraphs);
11152
11732
  }
@@ -11175,7 +11755,7 @@ function createPFrameForGraphs(ctx, blockColumns) {
11175
11755
  }));
11176
11756
  }
11177
11757
  //#endregion
11178
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/filters/traverse.js
11758
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/filters/traverse.js
11179
11759
  /**
11180
11760
  * Recursively traverses a FilterSpec tree bottom-up, applying visitor callbacks.
11181
11761
  *
@@ -11214,7 +11794,7 @@ function collectFilterSpecColumns(filter) {
11214
11794
  });
11215
11795
  }
11216
11796
  //#endregion
11217
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/filters/converters/filterToQuery.js
11797
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/filters/converters/filterToQuery.js
11218
11798
  /** Converts a QueryColumnId object into a SpecQueryExpression reference. */
11219
11799
  function resolveColumnRef(col) {
11220
11800
  return col.type === "axis" ? {
@@ -11601,7 +12181,7 @@ function isEmpty(value) {
11601
12181
  return true;
11602
12182
  }
11603
12183
  //#endregion
11604
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/filters/distill.js
12184
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/filters/distill.js
11605
12185
  /**
11606
12186
  * Strips non-FilterSpec metadata (whitelist approach) and removes
11607
12187
  * unfilled leaves (type is undefined or any required field is undefined).
@@ -11706,7 +12286,7 @@ const REQUIRED_KEYS_BY_TYPE = {
11706
12286
  greaterThanColumnOrEqual: ["column", "rhs"]
11707
12287
  };
11708
12288
  //#endregion
11709
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/components/PlDataTable/state-migration.js
12289
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/components/PlDataTable/state-migration.js
11710
12290
  /** Upgrade PlDataTableStateV2 to the latest version */
11711
12291
  function upgradePlDataTableStateV2(state) {
11712
12292
  if (!state) return createPlDataTableStateV2();
@@ -12064,7 +12644,7 @@ function parseLegacyLeafColumn(s) {
12064
12644
  return parsed;
12065
12645
  }
12066
12646
  //#endregion
12067
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/utils.js
12647
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/utils.js
12068
12648
  /** Adapt a {@link ColumnRecipe} to the plain {@link RuleColumn} shape. */
12069
12649
  function toRuleColumn(col) {
12070
12650
  return {
@@ -12162,7 +12742,7 @@ function deriveAllLabels(options) {
12162
12742
  })), deriveLabelsOptions).reduce((acc, label, index) => (acc[columns[index].id] = label, acc), {});
12163
12743
  }
12164
12744
  //#endregion
12165
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js
12745
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js
12166
12746
  /**
12167
12747
  * Assemble a ptable def directly from recipes. Each secondary recipe is its own
12168
12748
  * outer-joined subtree: `getQuery()` encodes its linker chain, and its
@@ -12226,7 +12806,7 @@ function columnToJoinEntry(col, qualifications) {
12226
12806
  };
12227
12807
  }
12228
12808
  //#endregion
12229
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/components/PlDataTable/columnResolver.js
12809
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/components/PlDataTable/columnResolver.js
12230
12810
  function createColumnResolver(columns, deps) {
12231
12811
  const axisIds = [];
12232
12812
  for (const c of columns) for (const ax of c.getSpec().axesSpec) axisIds.push(getAxisId(ax));
@@ -12250,7 +12830,7 @@ function createColumnResolver(columns, deps) {
12250
12830
  };
12251
12831
  }
12252
12832
  //#endregion
12253
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/discoverColumns.js
12833
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/discoverColumns.js
12254
12834
  /**
12255
12835
  * Discover columns from sources/anchors and split them into primary
12256
12836
  * (direct anchor hits — zero-hop, query is a bare column) and secondary
@@ -12296,7 +12876,7 @@ function discoverLabelColumns(ctx, primary) {
12296
12876
  }).getColumns();
12297
12877
  }
12298
12878
  //#endregion
12299
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.81.1/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js
12879
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.83.0/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js
12300
12880
  function createPlDataTableV3(ctx, options) {
12301
12881
  const state = upgradePlDataTableStateV2(options.tableState);
12302
12882
  const primaryJoinType = options.primaryJoinType ?? "full";
@@ -12659,6 +13239,180 @@ const ErrorShape = objectType({
12659
13239
  errors: lazyType(() => ErrorShape.array()).optional()
12660
13240
  });
12661
13241
  //#endregion
13242
+ //#region ../kind/dist/package.js
13243
+ var name = "@platforma-open/milaboratories.sort-seq-analysis.kind";
13244
+ var version = "1.0.1";
13245
+ //#endregion
13246
+ //#region ../node_modules/.pnpm/@platforma-sdk+block-kind@1.1.0/node_modules/@platforma-sdk/block-kind/dist/params.js
13247
+ /**
13248
+ * Establish that a value is an object whose fields a kind can read — the half of a params
13249
+ * check every kind needs and no two kinds differ on.
13250
+ *
13251
+ * Params that arrived from a template file are `unknown`, and before a single field can be
13252
+ * read the value has to be an object. Worth a shared function because the check is easy to
13253
+ * get wrong by hand: `typeof null` is `"object"`, `Object.keys(5)` is `[]` and
13254
+ * `Object.keys(["a"])` is `["0"]`, so a naive test lets `null`, a number and an array through
13255
+ * as if they were empty params.
13256
+ *
13257
+ * What each field must *be* is the kind's own business and stays in the kind, as plain
13258
+ * TypeScript: this package deliberately carries no validation library, so a kind author owes
13259
+ * it no schema.
13260
+ *
13261
+ * A key the kind does not declare is NOT refused. A parser returns the params to use, so a
13262
+ * field it never read is dropped and never reaches the block — the only question was whether
13263
+ * to also complain, and complaining costs more than it catches. It would mean each kind
13264
+ * restating its own field list as strings, with nothing checking that the list stayed in step
13265
+ * with the type: a field added to the contract and read by the parser, but missed in the list,
13266
+ * would turn into a kind that refuses files that are correct. What an unexpected key can
13267
+ * actually mean is a params contract from a different version of the kind, and that is
13268
+ * guarded where it belongs — by the version in the entry's `{name}@{selector}` reference.
13269
+ *
13270
+ * An assertion rather than a parser that returns a copy, so a kind reads its fields off the
13271
+ * value it was handed:
13272
+ *
13273
+ * ```ts
13274
+ * function parseInitializationParams(value: unknown): BlockParams {
13275
+ * assertParamsObject(value);
13276
+ *
13277
+ * const { numbers } = value;
13278
+ * if (numbers !== undefined && !isNumberArray(numbers)) {
13279
+ * throw new Error("'numbers' must be an array of numbers.");
13280
+ * }
13281
+ * return { numbers };
13282
+ * }
13283
+ * ```
13284
+ *
13285
+ * Messages are finished sentences addressed to whoever wrote the file, because that is who
13286
+ * reads them: a kind's rejection is reported against the entry that carried the params.
13287
+ *
13288
+ * @param value The params as they arrived
13289
+ * @throws if `value` is not an object
13290
+ */
13291
+ function assertParamsObject(value) {
13292
+ if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error(`Params must be an object, not ${describe(value)}.`);
13293
+ }
13294
+ /** What a value is, for a message that has to say why it is not an object. */
13295
+ function describe(value) {
13296
+ if (value === null) return "null";
13297
+ if (value === void 0) return "nothing";
13298
+ if (Array.isArray(value)) return "an array";
13299
+ return `a ${typeof value} (${JSON.stringify(value) ?? String(value)})`;
13300
+ }
13301
+ //#endregion
13302
+ //#region ../node_modules/.pnpm/@platforma-sdk+block-kind@1.1.0/node_modules/@platforma-sdk/block-kind/dist/index.js
13303
+ /**
13304
+ * Define a block kind.
13305
+ *
13306
+ * `meta` is the kind's identity — its own `{ name, version }`. Source it from
13307
+ * the package's `package.json` rather than hand-typing literals, so the on-wire
13308
+ * `{name}@{version}` cannot drift from what npm publishes and what the S3
13309
+ * manifest records (all read the same `package.json`):
13310
+ *
13311
+ * ```ts
13312
+ * // a kind package's src/index.ts
13313
+ * import { name, version } from "../package.json" with { type: "json" };
13314
+ * export const kind = defineBlockKind<Params>({ name, version });
13315
+ * ```
13316
+ *
13317
+ * rolldown inlines the JSON import (tree-shaken to the two strings) into the
13318
+ * bundled `kind.js`, so no build-time injection is needed.
13319
+ *
13320
+ * A kind must also declare `parseInitializationParams` — the runtime check applied to params
13321
+ * that came from a template file rather than from typed code. See
13322
+ * {@link CompiledBlockKind} for what it must do.
13323
+ *
13324
+ * @typeParam BlockParams - shape of the params a block of this kind reads. Pinned both
13325
+ * as a type and by `parseInitializationParams`, whose return type is checked against it.
13326
+ */
13327
+ function defineBlockKind(meta) {
13328
+ return Object.freeze({
13329
+ kindSchema: "v1",
13330
+ name: meta.name,
13331
+ version: meta.version,
13332
+ parseInitializationParams: meta.parseInitializationParams
13333
+ });
13334
+ }
13335
+ //#endregion
13336
+ //#region ../kind/dist/index.js
13337
+ /**
13338
+ * The same contract at runtime, for params arriving from a template file rather than from typed
13339
+ * code — the only point that can catch a hand-written entry being wrong.
13340
+ *
13341
+ * Each field the contract names is read and checked; nothing else is. A key this function never
13342
+ * reads is dropped rather than refused, so a misspelled key in a template file is not caught
13343
+ * here — it surfaces later as a block that started on its defaults. That cost is accepted: a
13344
+ * key-set check would mean this file keeping its own field names as strings, and nothing holds
13345
+ * that list in step with the type above.
13346
+ *
13347
+ * The checks stop at the shape of a value. That `gateOrder` names only values `gateValues`
13348
+ * carries, that a gate column is not also the condition column — those are refused by
13349
+ * `settingsIssues` in the model, where the whole configuration is in view. A parser stricter
13350
+ * than the settings drawer would make this block export a template its own kind then refuses to
13351
+ * apply.
13352
+ */
13353
+ function parseInitializationParams(value) {
13354
+ assertParamsObject(value);
13355
+ const { conditionColumnRef, gateColumnRef, sortFractionColumnRef, gateOrder, gateValues, gateColumnLabel, conditionValues } = value;
13356
+ return {
13357
+ conditionColumnRef: optionalColumnRef(conditionColumnRef, "conditionColumnRef"),
13358
+ gateColumnRef: optionalColumnRef(gateColumnRef, "gateColumnRef"),
13359
+ sortFractionColumnRef: optionalColumnRef(sortFractionColumnRef, "sortFractionColumnRef"),
13360
+ gateOrder: optionalStringList(gateOrder, "gateOrder"),
13361
+ gateValues: optionalStringList(gateValues, "gateValues"),
13362
+ gateColumnLabel: optionalString(gateColumnLabel, "gateColumnLabel"),
13363
+ conditionValues: optionalStringList(conditionValues, "conditionValues")
13364
+ };
13365
+ }
13366
+ /**
13367
+ * A column ref is a canonically serialized id, not a free string, so this checks the string
13368
+ * parses and that what comes out is a shape the SDK recognizes as a column id.
13369
+ *
13370
+ * **Not `isColumnUniversalId`, which is the obvious choice and the wrong one.** The block stores
13371
+ * what `AnchoredIdDeriver.deriveS` returns — an *anchored* id, `{name, type, domain, axes}` with
13372
+ * `{anchor, idx}` refs in the axes. `ColumnUniversalId` is a union of the PObject / filtered /
13373
+ * discovered / overridden key forms and does not include the anchored one, so
13374
+ * `isColumnUniversalId` returns `false` for every id this block actually holds. (The
13375
+ * `SUniversalPColumnId` name is a deprecated alias of `ColumnUniversalId`, which is what makes
13376
+ * the mistake look correct.) Verified against pl-model-common 1.48.0: an anchored id fails
13377
+ * `isColumnUniversalId` and passes `isAnchoredPColumnId`.
13378
+ *
13379
+ * `isColumnUniversalKey` is kept alongside so a ref that arrives in one of the other forms is
13380
+ * not refused for a reason that has nothing to do with the template being wrong.
13381
+ *
13382
+ * The cast is over a real check: both guards narrow the *parsed* value, and nothing in the SDK
13383
+ * narrows the string that carried it.
13384
+ */
13385
+ function optionalColumnRef(value, field) {
13386
+ if (value === void 0) return void 0;
13387
+ if (typeof value !== "string") throw new Error(`'${field}' must be a column id.`);
13388
+ let parsed;
13389
+ try {
13390
+ parsed = JSON.parse(value);
13391
+ } catch {
13392
+ throw new Error(`'${field}' must be a column id.`);
13393
+ }
13394
+ if (!isAnchoredPColumnId(parsed) && !isColumnUniversalKey(parsed)) throw new Error(`'${field}' must be a column id.`);
13395
+ return value;
13396
+ }
13397
+ function optionalString(value, field) {
13398
+ if (value === void 0) return void 0;
13399
+ if (typeof value !== "string") throw new Error(`'${field}' must be a string.`);
13400
+ return value;
13401
+ }
13402
+ function optionalStringList(value, field) {
13403
+ if (value === void 0) return void 0;
13404
+ if (!Array.isArray(value)) throw new Error(`'${field}' must be a list.`);
13405
+ return value.map((entry, index) => {
13406
+ if (typeof entry !== "string") throw new Error(`'${field}[${index}]' must be a string.`);
13407
+ return entry;
13408
+ });
13409
+ }
13410
+ const kind = defineBlockKind({
13411
+ name,
13412
+ version,
13413
+ parseInitializationParams
13414
+ });
13415
+ //#endregion
12662
13416
  //#region ../model/dist/dataModel.js
12663
13417
  /**
12664
13418
  * `readFloor` is deliberately absent rather than 0: those are different runs. Absent applies no
@@ -12666,12 +13420,16 @@ const ErrorShape = objectType({
12666
13420
  *
12667
13421
  * Later shape changes add `.migrate<Next>("Ver_…", prev => …)` links rather than editing this.
12668
13422
  */
12669
- const blockDataModel = new DataModelBuilder().from("Ver_2026_08_07").init(() => ({
12670
- gateOrder: [],
13423
+ const blockDataModel = new DataModelBuilder({ kind }).from("Ver_2026_08_07").init(({ params }) => ({
13424
+ conditionColumnRef: params?.conditionColumnRef,
13425
+ gateColumnRef: params?.gateColumnRef,
13426
+ sortFractionColumnRef: params?.sortFractionColumnRef,
13427
+ gateOrder: params?.gateOrder ?? [],
13428
+ gateValues: params?.gateValues ?? [],
13429
+ gateColumnLabel: params?.gateColumnLabel,
13430
+ conditionValues: params?.conditionValues ?? [],
12671
13431
  excludedConditions: [],
12672
- gateValues: [],
12673
13432
  customBlockLabel: "",
12674
- conditionValues: [],
12675
13433
  resultsTableState: createPlDataTableStateV2(),
12676
13434
  distributionGraphStates: {}
12677
13435
  }));
@@ -12681,10 +13439,9 @@ const blockDataModel = new DataModelBuilder().from("Ver_2026_08_07").init(() =>
12681
13439
  * Every configuration rule, checked here and **nowhere else**. These six are decidable from the
12682
13440
  * arguments and snapshotted column values alone, so they are refused before the run starts.
12683
13441
  *
12684
- * The two data-value rules — sort fractions, one sample per condition-and-gate group — belong
12685
- * to the computation and are deliberately not approximated here: a duplicated rule is one that
12686
- * will disagree, and it fails by drifting looser, so the settings pass and the run fails anyway
12687
- * with a different message.
13442
+ * The one data-value rule — sort fractions — belongs to the computation and is deliberately not
13443
+ * approximated here: a duplicated rule is one that will disagree, and it fails by drifting
13444
+ * looser, so the settings pass and the run fails anyway with a different message.
12688
13445
  */
12689
13446
  function settingsIssues(data) {
12690
13447
  const issues = [];
@@ -12742,7 +13499,10 @@ function distributionConditionsOf(columns) {
12742
13499
  function distributionPlotTitle(condition, entry) {
12743
13500
  return entry !== void 0 && entry.variantsPlotted < entry.variantsScored ? `Variant Frequency Top ${entry.variantsPlotted} — ${condition}` : `Variant Frequency — ${condition}`;
12744
13501
  }
12745
- const platforma$1 = BlockModelV3.create(blockDataModel).args((data) => {
13502
+ const platforma$1 = BlockModelV3.create({
13503
+ dataModel: blockDataModel,
13504
+ kind
13505
+ }).args((data) => {
12746
13506
  const issues = settingsIssues(data);
12747
13507
  if (issues.length > 0) throw new Error(issues.join("; "));
12748
13508
  return {
@@ -12772,16 +13532,35 @@ const platforma$1 = BlockModelV3.create(blockDataModel).args((data) => {
12772
13532
  const columns = ctx.resultPool.getAnchoredPColumns({ main: anchor }, [metadataSelector]);
12773
13533
  if (!columns || columns.length === 0) return void 0;
12774
13534
  return ctx.createPFrame(columns);
13535
+ }).output("sampleLabelPframe", (ctx) => {
13536
+ const anchor = ctx.data.abundanceRef;
13537
+ if (!anchor) return void 0;
13538
+ const columns = ctx.resultPool.getAnchoredPColumns({ main: anchor }, [sampleLabelSelector]);
13539
+ if (!columns || columns.length === 0) return void 0;
13540
+ return ctx.createPFrame(columns);
13541
+ }).output("sampleLabelColumnId", (ctx) => {
13542
+ const anchor = ctx.data.abundanceRef;
13543
+ if (!anchor) return void 0;
13544
+ return ctx.resultPool.getAnchoredPColumns({ main: anchor }, [sampleLabelSelector])?.[0]?.id;
12775
13545
  }).outputWithStatus("resultsTable", (ctx) => {
12776
- const columns = ctx.outputs?.resolve("scoresPf")?.getPColumns();
12777
- if (!columns) return void 0;
12778
- const anchor = columns.filter((column) => column.spec.name === FacsBin.GateRankMean).sort((a, b) => (a.spec.domain?.[FacsBin.ConditionDomain] ?? "").localeCompare(b.spec.domain?.[FacsBin.ConditionDomain] ?? ""))[0];
13546
+ const own = ctx.outputs?.resolve("scoresPf")?.getPColumns();
13547
+ if (!own) return void 0;
13548
+ const anchor = own.filter((column) => column.spec.name === FacsBin.GateRankMean).sort((a, b) => (a.spec.domain?.[FacsBin.ConditionDomain] ?? "").localeCompare(b.spec.domain?.[FacsBin.ConditionDomain] ?? ""))[0];
12779
13549
  if (!anchor) return void 0;
13550
+ const primaryColumns = own.map((column) => DataColumn.fromColumn(column));
13551
+ const { primary, secondary } = discoverTableColumns(ctx, {
13552
+ anchors: { main: anchor.spec },
13553
+ selector: {
13554
+ mode: "exact",
13555
+ exclude: [{ name: [{
13556
+ type: "regex",
13557
+ value: "^pl7\\.app/facsBin/.*$"
13558
+ }] }]
13559
+ }
13560
+ });
12780
13561
  return createPlDataTableV3(ctx, {
12781
- columns: {
12782
- anchors: { main: anchor.spec },
12783
- selector: { mode: "exact" }
12784
- },
13562
+ primaryColumns,
13563
+ columns: [...primary, ...secondary],
12785
13564
  tableState: ctx.data.resultsTableState,
12786
13565
  displayOptions: {
12787
13566
  /**
@@ -12792,6 +13571,9 @@ const platforma$1 = BlockModelV3.create(blockDataModel).args((data) => {
12792
13571
  * `optional` rather than `hidden` for the remainder: they stay one click away in the
12793
13572
  * column picker. Hiding a column a user wants, with no way to bring it back, is the
12794
13573
  * worse failure.
13574
+ *
13575
+ * The two score rules are the block's own columns, which are primary and therefore
13576
+ * always on screen; the rules state their visibility for the column picker's sake.
12795
13577
  */
12796
13578
  visibility: [
12797
13579
  {
@@ -12831,7 +13613,15 @@ visibility: [
12831
13613
  id: column.id,
12832
13614
  spec: column.spec
12833
13615
  }));
12834
- }).output("manifest", (ctx) => ctx.outputs?.resolve("manifest")?.getDataAsJsonOrUndefined()).output("logHandle", (ctx) => ctx.outputs?.resolve("logHandle")?.getLogHandle()).output("isRunning", (ctx) => ctx.outputs?.getIsReadyOrError() === false).output("settingsIssues", (ctx) => settingsIssues(ctx.data)).output("defaultBlockLabel", (ctx) => deriveBlockLabel(ctx.data)).title(() => "Sort-Seq Analysis").subtitle((ctx) => ctx.data.customBlockLabel || deriveBlockLabel(ctx.data)).sections((ctx) => {
13616
+ }).output("manifest", (ctx) => ctx.outputs?.resolve("manifest")?.getDataAsJsonOrUndefined()).output("logHandle", (ctx) => ctx.outputs?.resolve("logHandle")?.getLogHandle()).output("isRunning", (ctx) => ctx.outputs?.getIsReadyOrError() === false).output("settingsIssues", (ctx) => settingsIssues(ctx.data)).output("defaultBlockLabel", (ctx) => deriveBlockLabel(ctx.data)).templateParams((data) => ({
13617
+ conditionColumnRef: data.conditionColumnRef,
13618
+ gateColumnRef: data.gateColumnRef,
13619
+ sortFractionColumnRef: data.sortFractionColumnRef,
13620
+ gateOrder: data.gateOrder,
13621
+ gateValues: data.gateValues,
13622
+ gateColumnLabel: data.gateColumnLabel,
13623
+ conditionValues: data.conditionValues
13624
+ })).title(() => "Sort-Seq Analysis").subtitle((ctx) => ctx.data.customBlockLabel || deriveBlockLabel(ctx.data)).sections((ctx) => {
12835
13625
  const columns = ctx.outputs?.resolve("distributionPf")?.getPColumns();
12836
13626
  return [{
12837
13627
  type: "link",