@framesquared/data 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -939,8 +939,8 @@ declare class WebSocketProxy extends Proxy {
939
939
  create(operation: Operation): Promise<ResultSet>;
940
940
  update(operation: Operation): Promise<ResultSet>;
941
941
  destroy(operation: Operation): Promise<ResultSet>;
942
- on(event: string, fn: Function): void;
943
- off(event: string, fn: Function): void;
942
+ on(event: string, fn: (...args: any[]) => void): void;
943
+ off(event: string, fn: (...args: any[]) => void): void;
944
944
  private fire;
945
945
  }
946
946
 
package/dist/index.js CHANGED
@@ -928,6 +928,7 @@ var Collection = class {
928
928
  toArray() {
929
929
  return [...this.items];
930
930
  }
931
+ // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
931
932
  each(fn) {
932
933
  for (let i = 0; i < this.items.length; i++) {
933
934
  if (fn(this.items[i], i) === false) break;
@@ -1153,6 +1154,7 @@ var Store = class extends Base2 {
1153
1154
  last() {
1154
1155
  return this.data.last();
1155
1156
  }
1157
+ // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
1156
1158
  each(fn) {
1157
1159
  this.data.each(fn);
1158
1160
  }
@@ -1406,8 +1408,7 @@ var XmlReader = class {
1406
1408
  (f) => typeof f === "string" ? f : f.name
1407
1409
  );
1408
1410
  const records = [];
1409
- for (let i = 0; i < nodes.length; i++) {
1410
- const node = nodes[i];
1411
+ for (const node of nodes) {
1411
1412
  const obj = {};
1412
1413
  for (const fieldName of fieldNames) {
1413
1414
  let el = node.getElementsByTagName(fieldName)[0];
@@ -2580,6 +2581,7 @@ var WebSocketProxy = class extends Proxy2 {
2580
2581
  reconnect;
2581
2582
  reconnectInterval;
2582
2583
  ws = null;
2584
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2583
2585
  listeners = {};
2584
2586
  intentionalClose = false;
2585
2587
  reconnectTimer = null;
@@ -2655,9 +2657,11 @@ var WebSocketProxy = class extends Proxy2 {
2655
2657
  // -----------------------------------------------------------------------
2656
2658
  // Events
2657
2659
  // -----------------------------------------------------------------------
2660
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2658
2661
  on(event, fn) {
2659
2662
  (this.listeners[event] ??= []).push(fn);
2660
2663
  }
2664
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2661
2665
  off(event, fn) {
2662
2666
  const list = this.listeners[event];
2663
2667
  if (!list) return;
@@ -2701,20 +2705,24 @@ var BatchProxy = class extends Proxy2 {
2701
2705
  if (data.results && Array.isArray(data.results)) {
2702
2706
  for (const r of data.results) {
2703
2707
  const records = (r.records ?? []).map((item) => this.model.create(item));
2704
- results.push(new ResultSet({
2705
- records,
2706
- success: r.success ?? false,
2707
- message: r.message
2708
- }));
2708
+ results.push(
2709
+ new ResultSet({
2710
+ records,
2711
+ success: r.success ?? false,
2712
+ message: r.message
2713
+ })
2714
+ );
2709
2715
  }
2710
2716
  }
2711
2717
  return results;
2712
2718
  } catch (err) {
2713
- return operations.map(() => new ResultSet({
2714
- records: [],
2715
- success: false,
2716
- message: err?.message ?? "Batch request failed"
2717
- }));
2719
+ return operations.map(
2720
+ () => new ResultSet({
2721
+ records: [],
2722
+ success: false,
2723
+ message: err?.message ?? "Batch request failed"
2724
+ })
2725
+ );
2718
2726
  }
2719
2727
  }
2720
2728
  // Proxy interface — delegate to sendBatch with single operation
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/Model.ts","../src/field/Field.ts","../src/association/Association.ts","../src/association/HasOne.ts","../src/association/HasMany.ts","../src/association/BelongsTo.ts","../src/association/ManyToMany.ts","../src/Schema.ts","../src/ModelCollection.ts","../src/validators.ts","../src/store/Store.ts","../src/store/Collection.ts","../src/ResultSet.ts","../src/reader/Reader.ts","../src/writer/Writer.ts","../src/proxy/Proxy.ts","../src/proxy/ClientProxy.ts","../src/proxy/ServerProxy.ts","../src/store/TreeStore.ts","../src/mixin/NodeInterface.ts","../src/model/TreeModel.ts","../src/reader/TreeReader.ts","../src/writer/TreeWriter.ts","../src/store/BufferedStore.ts","../src/proxy/GraphQLProxy.ts","../src/proxy/WebSocketProxy.ts","../src/proxy/BatchProxy.ts","../src/data/Connection.ts","../src/data/Session.ts"],"sourcesContent":["/**\n * @framesquared/data – Model\n *\n * The foundation of the data layer. A Model represents a record with\n * typed fields, dirty tracking, validation, and event notification.\n *\n * Instances are wrapped in a Proxy so `record.name` transparently\n * delegates to `get('name')` / `set('name', value)` for field access.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { Base, Observable } from '@framesquared/core';\nimport { Field, createField } from './field/Field.js';\nimport type { FieldDefinition } from './field/Field.js';\nimport { Schema } from './Schema.js';\nimport type { Association } from './association/Association.js';\nimport { ModelCollection, ManyToManyCollection } from './ModelCollection.js';\n\n// ---------------------------------------------------------------------------\n// ValidationResult\n// ---------------------------------------------------------------------------\n\nexport interface ValidationError {\n field: string;\n message: string;\n}\n\nexport interface ValidationResult {\n valid: boolean;\n errors: ValidationError[];\n}\n\n// ---------------------------------------------------------------------------\n// Field resolution helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Resolves a dot-separated mapping path from raw data.\n */\nfunction getNestedValue(data: Record<string, unknown>, path: string): unknown {\n const segments = path.split('.');\n let current: unknown = data;\n for (const seg of segments) {\n if (current === null || current === undefined || typeof current !== 'object') {\n return undefined;\n }\n current = (current as Record<string, unknown>)[seg];\n }\n return current;\n}\n\n// ---------------------------------------------------------------------------\n// Proxy handler\n// ---------------------------------------------------------------------------\n\nconst MODEL_PROPS = new Set<string | symbol>([\n // Commonly accessed non-field properties/methods that should NOT\n // be intercepted by the proxy's field get/set logic.\n 'constructor', 'prototype', '__proto__',\n 'get', 'set', 'getData', 'getId', 'setId',\n 'isModified', 'getChanges', 'commit', 'reject', 'validate', 'isValid',\n 'on', 'un', 'fireEvent', 'fireEventArgs', 'addListener', 'removeListener',\n 'hasListener', 'clearListeners', 'suspendEvents', 'resumeEvents', 'isSuspended',\n 'mon', 'mun', 'relayEvents', 'fireEventedAction',\n 'destroy', 'isDestroyed', '$destroyHooks',\n '$className', 'self', '$callStack', '$configInitialized', '$pendingConfig',\n 'hasMixin', 'initConfig', 'callParent',\n 'modified', 'phantom',\n '$associations', '$fieldMap', '$data',\n Symbol.dispose, Symbol.toPrimitive, Symbol.toStringTag,\n]);\n\nfunction createModelProxy(model: Model): Model {\n return new Proxy(model, {\n get(target, prop, receiver) {\n // If it's a known Model/Base property or symbol, use normal access\n if (MODEL_PROPS.has(prop) || typeof prop === 'symbol') {\n return Reflect.get(target, prop, receiver);\n }\n // If it exists directly on the instance or prototype, use normal access\n if (prop in target) {\n const desc = Object.getOwnPropertyDescriptor(target, prop)\n ?? Object.getOwnPropertyDescriptor(Object.getPrototypeOf(target), prop);\n if (desc?.get || typeof desc?.value === 'function') {\n return Reflect.get(target, prop, receiver);\n }\n }\n // Check if it's a field name\n if (typeof prop === 'string' && target.$fieldMap?.has(prop)) {\n return target.get(prop);\n }\n return Reflect.get(target, prop, receiver);\n },\n set(target, prop, value, receiver) {\n if (typeof prop === 'string' && target.$fieldMap?.has(prop)) {\n target.set(prop, value);\n return true;\n }\n return Reflect.set(target, prop, value, receiver);\n },\n });\n}\n\n// ---------------------------------------------------------------------------\n// Model class\n// ---------------------------------------------------------------------------\n\n// Register the Observable mixin class (defined by core's define())\nconst ObservableMixin: typeof Base = Observable;\n\nexport class Model extends Base {\n static override $className = 'Ext.data.Model';\n\n /** Field definitions — override in subclasses. */\n static fields: (FieldDefinition | string)[] = [];\n\n /** Name of the ID field. */\n static idProperty = 'id';\n\n // -- Instance state (non-enumerable to keep proxy clean) --\n\n /** Resolved Field instances keyed by name. */\n $fieldMap!: Map<string, Field>;\n\n /** Current field values. */\n $data!: Record<string, unknown>;\n\n /** Previous values for dirty fields (fieldName → old value). */\n modified: Record<string, unknown> = {};\n\n /** Per-instance association storage: assocName → Model | ModelCollection */\n $associations: Map<string, Model | ModelCollection | ManyToManyCollection> = new Map();\n\n // -----------------------------------------------------------------------\n // Construction\n // -----------------------------------------------------------------------\n\n constructor(_data?: Record<string, unknown>) {\n super();\n // Will be called by create() which sets up fields + proxy\n }\n\n /**\n * Factory method that sets up fields, applies data, wraps in proxy.\n */\n static override create(this: typeof Model, data?: Record<string, unknown>): Model {\n const instance = new this();\n instance.$fieldMap = new Map();\n instance.$data = {};\n instance.modified = {};\n instance.$associations = new Map();\n\n // Resolve field definitions\n const fieldDefs = (this as any).fields as (FieldDefinition | string)[];\n for (const def of fieldDefs) {\n const field = createField(def);\n instance.$fieldMap.set(field.name, field);\n }\n\n // Apply Observable mixin methods if not already present\n ensureObservable(instance);\n\n // Load initial data\n instance.$loadData(data ?? {});\n\n // Process associations — install getters/setters, load nested data\n installAssociations(instance, data ?? {});\n\n // Wrap in proxy\n return createModelProxy(instance);\n }\n\n // -----------------------------------------------------------------------\n // Data loading (initial — not dirty)\n // -----------------------------------------------------------------------\n\n /** @internal Loads initial data without marking as dirty. */\n $loadData(rawData: Record<string, unknown>): void {\n // Store non-schema fields as-is (pass-through for custom data)\n for (const [key, value] of Object.entries(rawData)) {\n if (!this.$fieldMap.has(key)) {\n this.$data[key] = value;\n }\n }\n\n for (const [name, field] of this.$fieldMap) {\n let value: unknown;\n\n // Check mapping first\n if (field.mapping) {\n value = getNestedValue(rawData, field.mapping);\n } else {\n value = rawData[name];\n }\n\n // Apply field conversion\n if (value !== undefined) {\n value = field.convert(value, this);\n } else {\n value = field.defaultValue;\n if (value !== undefined) {\n value = field.convert(value, this);\n }\n }\n\n this.$data[name] = value;\n }\n }\n\n // -----------------------------------------------------------------------\n // get / set\n // -----------------------------------------------------------------------\n\n get(fieldName: string): unknown {\n return this.$data[fieldName];\n }\n\n set(fieldNameOrData: string | Record<string, unknown>, value?: unknown): string[] {\n const changes: Record<string, unknown> =\n typeof fieldNameOrData === 'string'\n ? { [fieldNameOrData]: value }\n : fieldNameOrData;\n\n const modifiedFields: string[] = [];\n\n for (const [name, newValue] of Object.entries(changes)) {\n const field = this.$fieldMap.get(name);\n if (!field) {\n // Pass-through for non-schema fields\n const oldValue = this.$data[name];\n if (newValue !== oldValue) {\n if (!(name in this.modified)) this.modified[name] = oldValue;\n this.$data[name] = newValue;\n modifiedFields.push(name);\n }\n continue;\n }\n\n const converted = field.convert(newValue, this);\n const oldValue = this.$data[name];\n\n if (converted === oldValue) continue;\n\n // Track dirty state — only store the first original value\n if (!(name in this.modified)) {\n this.modified[name] = oldValue;\n }\n\n this.$data[name] = converted;\n modifiedFields.push(name);\n\n // Fire idchanged if the id field changed\n const Ctor = this.constructor as typeof Model;\n if (name === Ctor.idProperty && typeof (this as any).fireEvent === 'function') {\n (this as any).fireEvent('idchanged', this, converted, oldValue);\n }\n }\n\n if (modifiedFields.length > 0 && typeof (this as any).fireEvent === 'function') {\n (this as any).fireEvent('change', this, modifiedFields);\n }\n\n return modifiedFields;\n }\n\n getData(options?: { serialize?: boolean }): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [name, field] of this.$fieldMap) {\n const value = this.$data[name];\n result[name] = options?.serialize ? field.serialize(value, this) : value;\n }\n return result;\n }\n\n // -----------------------------------------------------------------------\n // Dirty tracking\n // -----------------------------------------------------------------------\n\n isModified(fieldName?: string): boolean {\n if (fieldName) {\n return fieldName in this.modified;\n }\n return Object.keys(this.modified).length > 0;\n }\n\n getChanges(): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const name of Object.keys(this.modified)) {\n result[name] = this.$data[name];\n }\n return result;\n }\n\n commit(silent?: boolean): void {\n this.modified = {};\n if (!silent && typeof (this as any).fireEvent === 'function') {\n (this as any).fireEvent('commit', this);\n }\n }\n\n reject(silent?: boolean): void {\n // Revert to previous values\n for (const [name, oldValue] of Object.entries(this.modified)) {\n this.$data[name] = oldValue;\n }\n this.modified = {};\n if (!silent && typeof (this as any).fireEvent === 'function') {\n (this as any).fireEvent('reject', this);\n }\n }\n\n // -----------------------------------------------------------------------\n // Identification\n // -----------------------------------------------------------------------\n\n getId(): string | number {\n const Ctor = this.constructor as typeof Model;\n return this.$data[Ctor.idProperty] as string | number;\n }\n\n setId(id: string | number): void {\n const Ctor = this.constructor as typeof Model;\n this.set(Ctor.idProperty, id);\n }\n\n get phantom(): boolean {\n const id = this.getId();\n return id === undefined || id === null || id === 0 || id === '';\n }\n\n // -----------------------------------------------------------------------\n // Validation\n // -----------------------------------------------------------------------\n\n validate(): ValidationResult {\n const errors: ValidationError[] = [];\n\n for (const [name, field] of this.$fieldMap) {\n const value = this.$data[name];\n for (const validator of field.validators) {\n const msg = validator(value, this);\n if (msg) {\n errors.push({ field: name, message: msg });\n }\n }\n }\n\n return { valid: errors.length === 0, errors };\n }\n\n isValid(): boolean {\n return this.validate().valid;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Observable mixin integration\n// ---------------------------------------------------------------------------\n\n/**\n * Ensures the Observable mixin methods are available on the instance.\n * We copy prototype methods from Observable to Model instances at runtime.\n */\nfunction ensureObservable(instance: Model): void {\n const proto = ObservableMixin.prototype;\n for (const name of Object.getOwnPropertyNames(proto)) {\n if (name === 'constructor') continue;\n if (name in instance) continue;\n const desc = Object.getOwnPropertyDescriptor(proto, name);\n if (desc && typeof desc.value === 'function') {\n (instance as any)[name] = desc.value.bind(instance);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Association integration\n// ---------------------------------------------------------------------------\n\n/**\n * Processes all associations for the given instance's model class.\n * Installs getters/setters, loads nested data, sets up cascade hooks.\n */\nfunction installAssociations(\n instance: Model,\n rawData: Record<string, unknown>,\n): void {\n const modelName = (instance.constructor as typeof Model).$className;\n const assocs = Schema.getAssociations(modelName);\n if (assocs.length === 0) return;\n\n for (const assoc of assocs) {\n if (!assoc.associatedModel) continue;\n\n switch (assoc.type) {\n case 'hasOne':\n installHasOne(instance, assoc, rawData);\n break;\n case 'hasMany':\n installHasMany(instance, assoc, rawData);\n break;\n case 'belongsTo':\n installBelongsTo(instance, assoc, rawData);\n break;\n case 'manyToMany':\n installManyToMany(instance, assoc, rawData);\n break;\n }\n }\n}\n\nfunction installHasOne(\n instance: Model,\n assoc: Association,\n rawData: Record<string, unknown>,\n): void {\n const AssocModel = assoc.associatedModel!;\n const name = assoc.associationName;\n const getterName = assoc.getterName;\n const setterName = assoc.setterName;\n\n // Initialise storage\n instance.$associations.set(name, null as any);\n\n // Getter\n (instance as any)[getterName] = function (): Model | null {\n return (instance.$associations.get(name) as Model) ?? null;\n };\n\n // Setter\n (instance as any)[setterName] = function (child: Model): void {\n instance.$associations.set(name, child);\n // Set foreignKey on child pointing back to this parent\n const parentId = instance.get(assoc.primaryKey);\n if (parentId !== undefined && child.$fieldMap?.has(assoc.foreignKey)) {\n child.set(assoc.foreignKey, parentId);\n }\n };\n\n // Load from nested data\n const nestedData = rawData[name];\n if (nestedData && typeof nestedData === 'object' && !Array.isArray(nestedData)) {\n const childData = { ...nestedData as Record<string, unknown> };\n // Set foreignKey\n const parentId = instance.get(assoc.primaryKey);\n if (parentId !== undefined) {\n childData[assoc.foreignKey] = parentId;\n }\n const child = AssocModel.create(childData);\n instance.$associations.set(name, child);\n }\n\n // Cascade destroy\n if (assoc.cascade) {\n instance.$destroyHooks.push(() => {\n const child = instance.$associations.get(name) as Model | null;\n if (child && !child.isDestroyed) child.destroy();\n });\n }\n}\n\nfunction installHasMany(\n instance: Model,\n assoc: Association,\n rawData: Record<string, unknown>,\n): void {\n const AssocModel = assoc.associatedModel!;\n const name = assoc.associationName;\n const collection = new ModelCollection();\n instance.$associations.set(name, collection);\n\n // Collection accessor — wraps add() to auto-set foreignKey\n const wrappedCollection = {\n getCount: () => collection.getCount(),\n getAll: () => collection.getAll(),\n getById: (id: string | number) => collection.getById(id),\n filter: (fn: (record: Model) => boolean) => collection.filter(fn),\n add(child: Model) {\n const parentId = instance.get(assoc.primaryKey);\n if (parentId !== undefined && child.$fieldMap?.has(assoc.foreignKey)) {\n child.set(assoc.foreignKey, parentId);\n }\n collection.add(child);\n },\n remove(child: Model) {\n collection.remove(child);\n },\n };\n\n // Accessor method (e.g., user.orders())\n (instance as any)[name] = function () {\n return wrappedCollection;\n };\n\n // Load from nested data\n const nestedData = rawData[name];\n if (Array.isArray(nestedData)) {\n const parentId = instance.get(assoc.primaryKey);\n for (const itemData of nestedData) {\n if (typeof itemData === 'object' && itemData !== null) {\n const childData = { ...itemData as Record<string, unknown> };\n if (parentId !== undefined) {\n childData[assoc.foreignKey] = parentId;\n }\n const child = AssocModel.create(childData);\n collection.add(child);\n }\n }\n }\n\n // Cascade destroy\n if (assoc.cascade) {\n instance.$destroyHooks.push(() => {\n collection.destroyAll();\n });\n }\n}\n\nfunction installBelongsTo(\n instance: Model,\n assoc: Association,\n rawData: Record<string, unknown>,\n): void {\n const AssocModel = assoc.associatedModel!;\n const name = assoc.associationName;\n const getterName = assoc.getterName;\n const setterName = assoc.setterName;\n\n // Initialise storage\n instance.$associations.set(name, null as any);\n\n // Getter\n (instance as any)[getterName] = function (): Model | null {\n return (instance.$associations.get(name) as Model) ?? null;\n };\n\n // Setter\n (instance as any)[setterName] = function (parent: Model): void {\n instance.$associations.set(name, parent);\n // Update foreignKey on self\n const parentId = parent.get(assoc.primaryKey);\n if (parentId !== undefined && instance.$fieldMap?.has(assoc.foreignKey)) {\n instance.set(assoc.foreignKey, parentId);\n }\n };\n\n // Load from nested data\n const nestedData = rawData[name];\n if (nestedData && typeof nestedData === 'object' && !Array.isArray(nestedData)) {\n const parent = AssocModel.create(nestedData as Record<string, unknown>);\n instance.$associations.set(name, parent);\n }\n}\n\nfunction installManyToMany(\n instance: Model,\n assoc: Association,\n rawData: Record<string, unknown>,\n): void {\n const AssocModel = assoc.associatedModel!;\n const name = assoc.associationName;\n const collection = new ManyToManyCollection();\n instance.$associations.set(name, collection);\n\n // Accessor method\n (instance as any)[name] = function () {\n return collection;\n };\n\n // Load from nested data\n const nestedData = rawData[name];\n if (Array.isArray(nestedData)) {\n for (const itemData of nestedData) {\n if (typeof itemData === 'object' && itemData !== null) {\n const child = AssocModel.create(itemData as Record<string, unknown>);\n collection.link(child);\n }\n }\n }\n}\n","/**\n * @framesquared/data – Field system\n *\n * Defines field types with type coercion, serialization, and defaults.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\n// ---------------------------------------------------------------------------\n// FieldType enum\n// ---------------------------------------------------------------------------\n\nexport enum FieldType {\n STRING = 'string',\n INT = 'int',\n FLOAT = 'float',\n BOOLEAN = 'boolean',\n DATE = 'date',\n AUTO = 'auto',\n}\n\n// ---------------------------------------------------------------------------\n// Validator type (function signature)\n// ---------------------------------------------------------------------------\n\nexport type Validator = (value: unknown, record?: any) => string | null;\n\n// ---------------------------------------------------------------------------\n// FieldDefinition\n// ---------------------------------------------------------------------------\n\nexport interface FieldDefinition {\n name: string;\n type?: FieldType;\n defaultValue?: unknown;\n convert?: (value: unknown, record?: any) => unknown;\n serialize?: (value: unknown, record?: any) => unknown;\n mapping?: string;\n persist?: boolean;\n critical?: boolean;\n allowNull?: boolean;\n sortType?: string;\n validators?: Validator[];\n}\n\n// ---------------------------------------------------------------------------\n// Base Field class\n// ---------------------------------------------------------------------------\n\nexport abstract class Field {\n readonly name: string;\n readonly type: FieldType;\n readonly mapping: string | undefined;\n readonly persist: boolean;\n readonly critical: boolean;\n readonly allowNull: boolean;\n readonly sortType: string | undefined;\n readonly validators: Validator[];\n private readonly customConvert?: (value: unknown, record?: any) => unknown;\n private readonly customSerialize?: (value: unknown, record?: any) => unknown;\n private readonly customDefault: unknown;\n\n constructor(def: FieldDefinition) {\n this.name = def.name;\n this.type = def.type ?? FieldType.AUTO;\n this.mapping = def.mapping;\n this.persist = def.persist ?? true;\n this.critical = def.critical ?? false;\n this.allowNull = def.allowNull ?? false;\n this.sortType = def.sortType;\n this.validators = def.validators ?? [];\n this.customConvert = def.convert;\n this.customSerialize = def.serialize;\n this.customDefault = def.defaultValue;\n }\n\n /** Type-specific default (overridden by subclasses). */\n get defaultValue(): unknown {\n return this.customDefault !== undefined ? this.customDefault : this.getTypeDefault();\n }\n\n /** Subclass provides the type-specific default. */\n protected abstract getTypeDefault(): unknown;\n\n /**\n * Converts a raw value to the field's type.\n * If a custom `convert` was specified in the definition, it is used.\n * Otherwise delegates to the subclass's `coerce()`.\n */\n convert(value: unknown, record?: any): unknown {\n if (this.customConvert) {\n return this.customConvert(value, record);\n }\n if (value === null && this.allowNull) return null;\n if (value === undefined) return this.defaultValue;\n return this.coerce(value);\n }\n\n /** Type-specific coercion (subclasses override). */\n protected abstract coerce(value: unknown): unknown;\n\n /**\n * Serializes a value for transport.\n */\n serialize(value: unknown, record?: any): unknown {\n if (this.customSerialize) {\n return this.customSerialize(value, record);\n }\n return value;\n }\n}\n\n// ---------------------------------------------------------------------------\n// StringField\n// ---------------------------------------------------------------------------\n\nexport class StringField extends Field {\n constructor(def: Omit<FieldDefinition, 'type'> & { type?: FieldType }) {\n super({ ...def, type: FieldType.STRING });\n }\n\n protected getTypeDefault(): unknown { return ''; }\n\n protected coerce(value: unknown): unknown {\n if (value === null) return '';\n return String(value);\n }\n}\n\n// ---------------------------------------------------------------------------\n// IntField\n// ---------------------------------------------------------------------------\n\nexport class IntField extends Field {\n constructor(def: Omit<FieldDefinition, 'type'> & { type?: FieldType }) {\n super({ ...def, type: FieldType.INT });\n }\n\n protected getTypeDefault(): unknown { return 0; }\n\n protected coerce(value: unknown): unknown {\n if (value === null) return 0;\n if (typeof value === 'boolean') return value ? 1 : 0;\n const n = parseInt(String(value), 10);\n return Number.isNaN(n) ? 0 : n;\n }\n}\n\n// ---------------------------------------------------------------------------\n// FloatField\n// ---------------------------------------------------------------------------\n\nexport class FloatField extends Field {\n constructor(def: Omit<FieldDefinition, 'type'> & { type?: FieldType }) {\n super({ ...def, type: FieldType.FLOAT });\n }\n\n protected getTypeDefault(): unknown { return 0; }\n\n protected coerce(value: unknown): unknown {\n if (value === null) return 0;\n if (typeof value === 'boolean') return value ? 1 : 0;\n const n = parseFloat(String(value));\n return Number.isNaN(n) ? 0 : n;\n }\n}\n\n// ---------------------------------------------------------------------------\n// BooleanField\n// ---------------------------------------------------------------------------\n\nconst FALSE_STRINGS = new Set(['false', '0', 'no', 'off', '']);\n\nexport class BooleanField extends Field {\n constructor(def: Omit<FieldDefinition, 'type'> & { type?: FieldType }) {\n super({ ...def, type: FieldType.BOOLEAN });\n }\n\n protected getTypeDefault(): unknown { return false; }\n\n protected coerce(value: unknown): unknown {\n if (value === null || value === undefined) return false;\n if (typeof value === 'string') {\n return !FALSE_STRINGS.has(value.toLowerCase());\n }\n return Boolean(value);\n }\n}\n\n// ---------------------------------------------------------------------------\n// DateField\n// ---------------------------------------------------------------------------\n\nexport class DateField extends Field {\n constructor(def: Omit<FieldDefinition, 'type'> & { type?: FieldType }) {\n super({ ...def, type: FieldType.DATE });\n }\n\n protected getTypeDefault(): unknown { return null; }\n\n protected coerce(value: unknown): unknown {\n if (value instanceof Date) return value;\n if (typeof value === 'number') return new Date(value);\n if (typeof value === 'string') {\n const d = new Date(value);\n return Number.isNaN(d.getTime()) ? null : d;\n }\n return null;\n }\n\n override serialize(value: unknown): unknown {\n if (value instanceof Date) return value.toISOString();\n return value;\n }\n}\n\n// ---------------------------------------------------------------------------\n// AutoField\n// ---------------------------------------------------------------------------\n\nexport class AutoField extends Field {\n constructor(def: Omit<FieldDefinition, 'type'> & { type?: FieldType }) {\n super({ ...def, type: FieldType.AUTO });\n }\n\n protected getTypeDefault(): unknown { return undefined; }\n\n protected coerce(value: unknown): unknown {\n return value;\n }\n}\n\n// ---------------------------------------------------------------------------\n// createField factory\n// ---------------------------------------------------------------------------\n\nconst FIELD_CONSTRUCTORS: Record<string, new (def: FieldDefinition) => Field> = {\n [FieldType.STRING]: StringField,\n [FieldType.INT]: IntField,\n [FieldType.FLOAT]: FloatField,\n [FieldType.BOOLEAN]: BooleanField,\n [FieldType.DATE]: DateField,\n [FieldType.AUTO]: AutoField,\n};\n\n/**\n * Creates a Field instance from a definition or shorthand string.\n */\nexport function createField(def: FieldDefinition | string): Field {\n if (typeof def === 'string') {\n return new AutoField({ name: def });\n }\n const type = def.type ?? FieldType.AUTO;\n const Ctor = FIELD_CONSTRUCTORS[type] ?? AutoField;\n return new Ctor(def);\n}\n","/**\n * @framesquared/data – Association (base class)\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { Model } from '../Model.js';\n\nexport interface AssociationConfig {\n model: string | typeof Model;\n foreignKey: string;\n primaryKey?: string;\n getterName?: string;\n setterName?: string;\n cascade?: boolean;\n /** For ManyToMany: junction model name or class */\n through?: string;\n /** For ManyToMany: the other foreign key in the junction */\n otherKey?: string;\n}\n\nexport type AssociationType = 'hasOne' | 'hasMany' | 'belongsTo' | 'manyToMany';\n\nexport class Association {\n readonly type: AssociationType;\n readonly config: AssociationConfig;\n readonly ownerModelName: string;\n\n /** Resolved associated model class (may be null until forward ref resolves). */\n associatedModel: typeof Model | null = null;\n\n constructor(type: AssociationType, ownerModelName: string, config: AssociationConfig) {\n this.type = type;\n this.ownerModelName = ownerModelName;\n this.config = config;\n }\n\n /**\n * The property name used for nested JSON loading and as the\n * default getter/collection accessor name.\n */\n get associationName(): string {\n if (!this.associatedModel) return '';\n // Derive from classname: 'test.Address' → 'address', 'test.Order' → 'orders'\n const raw = this.associatedModel.$className.split('.').pop()!;\n const lower = raw[0].toLowerCase() + raw.slice(1);\n if (this.type === 'hasMany' || this.type === 'manyToMany') {\n // Simple pluralise: add 's'\n return lower.endsWith('s') ? lower : lower + 's';\n }\n return lower;\n }\n\n get getterName(): string {\n if (this.config.getterName) return this.config.getterName;\n const name = this.associationName;\n return `get${name[0].toUpperCase()}${name.slice(1)}`;\n }\n\n get setterName(): string {\n if (this.config.setterName) return this.config.setterName;\n const name = this.associationName;\n return `set${name[0].toUpperCase()}${name.slice(1)}`;\n }\n\n get foreignKey(): string {\n return this.config.foreignKey;\n }\n\n get primaryKey(): string {\n return this.config.primaryKey ?? 'id';\n }\n\n get cascade(): boolean {\n return this.config.cascade ?? false;\n }\n}\n","/**\n * @framesquared/data – HasOne association\n */\nimport { Association } from './Association.js';\nimport type { AssociationConfig } from './Association.js';\n\nexport class HasOne extends Association {\n constructor(ownerModelName: string, config: AssociationConfig) {\n super('hasOne', ownerModelName, config);\n }\n}\n","/**\n * @framesquared/data – HasMany association\n */\nimport { Association } from './Association.js';\nimport type { AssociationConfig } from './Association.js';\n\nexport class HasMany extends Association {\n constructor(ownerModelName: string, config: AssociationConfig) {\n super('hasMany', ownerModelName, config);\n }\n}\n","/**\n * @framesquared/data – BelongsTo association\n */\nimport { Association } from './Association.js';\nimport type { AssociationConfig } from './Association.js';\n\nexport class BelongsTo extends Association {\n constructor(ownerModelName: string, config: AssociationConfig) {\n super('belongsTo', ownerModelName, config);\n }\n}\n","/**\n * @framesquared/data – ManyToMany association\n */\nimport { Association } from './Association.js';\nimport type { AssociationConfig } from './Association.js';\n\nexport class ManyToMany extends Association {\n constructor(ownerModelName: string, config: AssociationConfig) {\n super('manyToMany', ownerModelName, config);\n }\n\n get through(): string {\n return this.config.through ?? '';\n }\n\n get otherKey(): string {\n return this.config.otherKey ?? '';\n }\n}\n","/**\n * @framesquared/data – Schema\n *\n * Singleton registry for Model classes and their associations.\n * Handles forward references: if Model A declares an association to\n * Model B by string name before B is registered, the reference is\n * resolved when B is later registered.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { Model } from './Model.js';\nimport { Association } from './association/Association.js';\nimport type { AssociationConfig } from './association/Association.js';\nimport { HasOne } from './association/HasOne.js';\nimport { HasMany } from './association/HasMany.js';\nimport { BelongsTo } from './association/BelongsTo.js';\nimport { ManyToMany } from './association/ManyToMany.js';\n\n// ---------------------------------------------------------------------------\n// Internal storage\n// ---------------------------------------------------------------------------\n\n/** className → Model class */\nconst models = new Map<string, typeof Model>();\n\n/** className → Association[] (owned by that model) */\nconst associations = new Map<string, Association[]>();\n\n/** modelName → list of unresolved Association references waiting for it */\nconst pendingReferences = new Map<string, Association[]>();\n\n// ---------------------------------------------------------------------------\n// SchemaImpl\n// ---------------------------------------------------------------------------\n\nclass SchemaImpl {\n /**\n * Registers a Model class and processes its association declarations.\n * If the model has `static hasOne`, `static hasMany`, `static belongsTo`,\n * or `static manyToMany` arrays, creates Association instances for each.\n */\n register(ModelClass: typeof Model): void {\n const name = ModelClass.$className;\n models.set(name, ModelClass);\n\n // Process association declarations\n this.processAssociations(ModelClass, 'hasOne', HasOne);\n this.processAssociations(ModelClass, 'hasMany', HasMany);\n this.processAssociations(ModelClass, 'belongsTo', BelongsTo);\n this.processAssociations(ModelClass, 'manyToMany', ManyToMany);\n\n // Resolve any pending forward references to this model\n const pending = pendingReferences.get(name);\n if (pending) {\n for (const assoc of pending) {\n assoc.associatedModel = ModelClass;\n }\n pendingReferences.delete(name);\n }\n }\n\n /**\n * Retrieves a registered Model class by name.\n */\n get(name: string): typeof Model | undefined {\n return models.get(name);\n }\n\n /**\n * Returns all Association instances owned by the given model name.\n */\n getAssociations(modelName: string): Association[] {\n return associations.get(modelName) ?? [];\n }\n\n /**\n * Clears all registrations (for testing).\n */\n clear(): void {\n models.clear();\n associations.clear();\n pendingReferences.clear();\n }\n\n // -----------------------------------------------------------------------\n // Internal: process static association arrays\n // -----------------------------------------------------------------------\n\n private processAssociations(\n ModelClass: typeof Model,\n staticProp: string,\n AssocClass: new (ownerName: string, config: AssociationConfig) => Association,\n ): void {\n const configs = (ModelClass as any)[staticProp] as AssociationConfig[] | undefined;\n if (!configs || !Array.isArray(configs)) return;\n\n const ownerName = ModelClass.$className;\n if (!associations.has(ownerName)) {\n associations.set(ownerName, []);\n }\n const list = associations.get(ownerName)!;\n\n for (const config of configs) {\n const assoc = new AssocClass(ownerName, config);\n\n // Resolve model reference\n const modelRef = config.model;\n if (typeof modelRef === 'string') {\n const resolved = models.get(modelRef);\n if (resolved) {\n assoc.associatedModel = resolved;\n } else {\n // Forward reference — park it for later resolution\n if (!pendingReferences.has(modelRef)) {\n pendingReferences.set(modelRef, []);\n }\n pendingReferences.get(modelRef)!.push(assoc);\n }\n } else {\n // Direct class reference\n assoc.associatedModel = modelRef as typeof Model;\n }\n\n list.push(assoc);\n }\n }\n}\n\n/** Singleton. */\nexport const Schema = new SchemaImpl();\n","/**\n * @framesquared/data – ModelCollection\n *\n * A lightweight collection of Model instances, used by HasMany and\n * ManyToMany associations. Provides add/remove/filter/getById.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { Model } from './Model.js';\n\nexport class ModelCollection {\n private items: Model[] = [];\n\n getCount(): number {\n return this.items.length;\n }\n\n getAll(): Model[] {\n return [...this.items];\n }\n\n add(record: Model): void {\n if (!this.items.includes(record)) {\n this.items.push(record);\n }\n }\n\n remove(record: Model): void {\n const idx = this.items.indexOf(record);\n if (idx !== -1) this.items.splice(idx, 1);\n }\n\n getById(id: string | number): Model | undefined {\n return this.items.find((r) => r.getId() === id);\n }\n\n filter(fn: (record: Model) => boolean): Model[] {\n return this.items.filter(fn);\n }\n\n destroyAll(): void {\n for (const item of this.items) {\n if (!item.isDestroyed) item.destroy();\n }\n this.items.length = 0;\n }\n}\n\n/**\n * Extended collection for ManyToMany that exposes link/unlink semantics.\n */\nexport class ManyToManyCollection extends ModelCollection {\n private junctions: Map<Model, any> = new Map();\n\n link(record: Model, _junctionData?: Record<string, unknown>): void {\n this.add(record);\n this.junctions.set(record, _junctionData ?? {});\n }\n\n unlink(record: Model): void {\n this.remove(record);\n this.junctions.delete(record);\n }\n}\n","/**\n * @framesquared/data – Built-in validators\n *\n * Each factory returns a Validator function: (value) => errorMsg | null\n */\n\nimport type { Validator } from './field/Field.js';\n\n/**\n * Value must not be null, undefined, or empty string.\n */\nexport function presence(message = 'is required'): Validator {\n return (value: unknown) => {\n if (value === null || value === undefined || value === '') {\n return message;\n }\n return null;\n };\n}\n\n/**\n * String length must be within min/max bounds.\n */\nexport function length(opts: { min?: number; max?: number; message?: string }): Validator {\n return (value: unknown) => {\n const str = String(value ?? '');\n if (opts.min !== undefined && str.length < opts.min) {\n return opts.message ?? `must be at least ${opts.min} characters`;\n }\n if (opts.max !== undefined && str.length > opts.max) {\n return opts.message ?? `must be at most ${opts.max} characters`;\n }\n return null;\n };\n}\n\n/**\n * Value must match the given regex.\n */\nexport function formatValidator(pattern: RegExp, message?: string): Validator {\n return (value: unknown) => {\n if (!pattern.test(String(value ?? ''))) {\n return message ?? `does not match the required format`;\n }\n return null;\n };\n}\n\n/**\n * Value must be in the allowed list.\n */\nexport function inclusion(list: unknown[], message?: string): Validator {\n return (value: unknown) => {\n if (!list.includes(value)) {\n return message ?? `must be one of: ${list.join(', ')}`;\n }\n return null;\n };\n}\n\n/**\n * Value must NOT be in the disallowed list.\n */\nexport function exclusion(list: unknown[], message?: string): Validator {\n return (value: unknown) => {\n if (list.includes(value)) {\n return message ?? `is not allowed`;\n }\n return null;\n };\n}\n\n/**\n * Numeric value must be within min/max.\n */\nexport function rangeValidator(opts: { min?: number; max?: number; message?: string }): Validator {\n return (value: unknown) => {\n const n = Number(value);\n if (opts.min !== undefined && n < opts.min) {\n return opts.message ?? `must be at least ${opts.min}`;\n }\n if (opts.max !== undefined && n > opts.max) {\n return opts.message ?? `must be at most ${opts.max}`;\n }\n return null;\n };\n}\n\n/**\n * Basic email format check.\n */\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\nexport function email(message = 'is not a valid email address'): Validator {\n return (value: unknown) => {\n if (!EMAIL_RE.test(String(value ?? ''))) {\n return message;\n }\n return null;\n };\n}\n","/**\n * @framesquared/data – Store\n *\n * A client-side collection of Model records with sorting, filtering,\n * grouping, events, and sync/change tracking.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { Base, Observable } from '@framesquared/core';\nimport type { Model } from '../Model.js';\nimport { Collection } from './Collection.js';\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface Sorter {\n property: string;\n direction: 'ASC' | 'DESC';\n sorterFn?: (a: Model, b: Model) => number;\n}\n\nexport type FilterOperator = '=' | '!=' | '<' | '<=' | '>' | '>=' | 'like' | 'in' | 'notin';\n\nexport interface Filter {\n property: string;\n value: unknown;\n operator?: FilterOperator;\n filterFn?: (record: Model) => boolean;\n anyMatch?: boolean;\n caseSensitive?: boolean;\n}\n\nexport interface Group {\n name: string;\n children: Model[];\n}\n\nexport interface StoreConfig {\n model: typeof Model;\n data?: Record<string, unknown>[];\n}\n\n// ---------------------------------------------------------------------------\n// Observable bootstrap — install mixin once on Store.prototype\n// ---------------------------------------------------------------------------\n\nconst ObservableMixin: typeof Base = Observable;\n\nfunction ensureObservable(instance: Store): void {\n const proto = ObservableMixin.prototype;\n for (const name of Object.getOwnPropertyNames(proto)) {\n if (name === 'constructor') continue;\n if (name in instance) continue;\n const desc = Object.getOwnPropertyDescriptor(proto, name);\n if (desc && typeof desc.value === 'function') {\n (instance as any)[name] = desc.value.bind(instance);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Filter matching\n// ---------------------------------------------------------------------------\n\nfunction matchFilter(record: Model, f: Filter): boolean {\n if (f.filterFn) return f.filterFn(record);\n\n const fieldValue = record.get(f.property);\n const filterValue = f.value;\n const op = f.operator ?? '=';\n const ci = !(f.caseSensitive ?? false);\n\n switch (op) {\n case '=':\n return fieldValue === filterValue;\n case '!=':\n return fieldValue !== filterValue;\n case '<':\n return (fieldValue as number) < (filterValue as number);\n case '<=':\n return (fieldValue as number) <= (filterValue as number);\n case '>':\n return (fieldValue as number) > (filterValue as number);\n case '>=':\n return (fieldValue as number) >= (filterValue as number);\n case 'like': {\n const sv = ci ? String(fieldValue).toLowerCase() : String(fieldValue);\n const fv = ci ? String(filterValue).toLowerCase() : String(filterValue);\n return sv.includes(fv);\n }\n case 'in':\n return Array.isArray(filterValue) && filterValue.includes(fieldValue);\n case 'notin':\n return Array.isArray(filterValue) && !filterValue.includes(fieldValue);\n default:\n return false;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Sorter comparator builder\n// ---------------------------------------------------------------------------\n\nfunction buildComparator(sorters: Sorter[]): (a: Model, b: Model) => number {\n return (a: Model, b: Model) => {\n for (const sorter of sorters) {\n if (sorter.sorterFn) {\n const result = sorter.sorterFn(a, b);\n if (result !== 0) return result;\n continue;\n }\n const va = a.get(sorter.property) as string | number;\n const vb = b.get(sorter.property) as string | number;\n const dir = sorter.direction === 'DESC' ? -1 : 1;\n if (va < vb) return -1 * dir;\n if (va > vb) return 1 * dir;\n }\n return 0;\n };\n}\n\n// ---------------------------------------------------------------------------\n// Store\n// ---------------------------------------------------------------------------\n\nexport class Store extends Base {\n static override $className = 'Ext.data.Store';\n\n private ModelClass: typeof Model;\n private data: Collection<Model>;\n private allData: Collection<Model>; // unfiltered snapshot\n private currentSorters: Sorter[] = [];\n private currentFilters: Filter[] = [];\n private groupField: string | null = null;\n private groupDirection: 'ASC' | 'DESC' = 'ASC';\n private cachedGroups: Group[] | null = null;\n private removedRecords: Model[] = [];\n\n // Observable state (populated by ensureObservable)\n $destroyHooks: (() => void)[] = [];\n\n constructor(config: StoreConfig) {\n super();\n ensureObservable(this);\n\n this.ModelClass = config.model;\n this.data = new Collection<Model>((r) => r.getId());\n this.allData = new Collection<Model>((r) => r.getId());\n\n if (config.data) {\n this.loadData(config.data);\n }\n }\n\n // -----------------------------------------------------------------------\n // Data loading\n // -----------------------------------------------------------------------\n\n private loadData(rawRecords: Record<string, unknown>[]): void {\n for (const raw of rawRecords) {\n const record = this.ModelClass.create(raw);\n this.data.add(record);\n this.allData.add(record);\n }\n }\n\n // -----------------------------------------------------------------------\n // CRUD\n // -----------------------------------------------------------------------\n\n add(...records: Model[]): Model[] {\n for (const record of records) {\n this.data.add(record);\n this.allData.add(record);\n }\n this.invalidateGroups();\n this.fire('add', this, records);\n this.fire('datachanged', this);\n return records;\n }\n\n insert(index: number, ...records: Model[]): Model[] {\n for (let i = 0; i < records.length; i++) {\n this.data.insert(index + i, records[i]);\n this.allData.add(records[i]);\n }\n this.invalidateGroups();\n this.fire('add', this, records, index);\n this.fire('datachanged', this);\n return records;\n }\n\n remove(...records: Model[]): Model[] {\n const removed: Model[] = [];\n for (const record of records) {\n if (this.data.remove(record)) {\n this.allData.remove(record);\n removed.push(record);\n if (!record.phantom) {\n this.removedRecords.push(record);\n }\n }\n }\n if (removed.length > 0) {\n this.invalidateGroups();\n this.fire('remove', this, removed);\n this.fire('datachanged', this);\n }\n return removed;\n }\n\n removeAt(index: number, count = 1): Model[] {\n const removed = this.data.removeAt(index, count);\n for (const record of removed) {\n this.allData.remove(record);\n if (!record.phantom) {\n this.removedRecords.push(record);\n }\n }\n if (removed.length > 0) {\n this.invalidateGroups();\n this.fire('remove', this, removed);\n this.fire('datachanged', this);\n }\n return removed;\n }\n\n removeAll(silent?: boolean): void {\n this.data.clear();\n this.allData.clear();\n this.invalidateGroups();\n if (!silent) {\n this.fire('clear', this);\n this.fire('datachanged', this);\n }\n }\n\n // -----------------------------------------------------------------------\n // Lookup\n // -----------------------------------------------------------------------\n\n getAt(index: number): Model | undefined {\n return this.data.getAt(index);\n }\n\n getById(id: string | number): Model | undefined {\n return this.data.getByKey(id);\n }\n\n getRange(start?: number, end?: number): Model[] {\n return this.data.getRange(start, end);\n }\n\n getCount(): number {\n return this.data.getCount();\n }\n\n getTotalCount(): number {\n return this.allData.getCount();\n }\n\n indexOf(record: Model): number {\n return this.data.indexOf(record);\n }\n\n contains(record: Model): boolean {\n return this.data.contains(record);\n }\n\n first(): Model | undefined {\n return this.data.first();\n }\n\n last(): Model | undefined {\n return this.data.last();\n }\n\n each(fn: (record: Model, index: number) => boolean | void): void {\n this.data.each(fn);\n }\n\n collect(fieldName: string): unknown[] {\n const seen = new Set<unknown>();\n this.data.each((r) => {\n seen.add(r.get(fieldName));\n });\n return [...seen];\n }\n\n getData(): Collection<Model> {\n return this.data;\n }\n\n // -----------------------------------------------------------------------\n // Sorting\n // -----------------------------------------------------------------------\n\n sort(fieldOrSorters?: string | Sorter[], direction: 'ASC' | 'DESC' = 'ASC'): void {\n if (typeof fieldOrSorters === 'string') {\n this.currentSorters = [{ property: fieldOrSorters, direction }];\n } else if (Array.isArray(fieldOrSorters)) {\n this.currentSorters = fieldOrSorters;\n }\n\n if (this.currentSorters.length > 0) {\n this.data.sort(buildComparator(this.currentSorters));\n }\n this.invalidateGroups();\n this.fire('sort', this, this.currentSorters);\n }\n\n getSorters(): Sorter[] {\n return [...this.currentSorters];\n }\n\n // -----------------------------------------------------------------------\n // Filtering\n // -----------------------------------------------------------------------\n\n filter(fieldOrFilters: string | Filter[], value?: unknown): void {\n if (typeof fieldOrFilters === 'string') {\n this.currentFilters = [{ property: fieldOrFilters, value }];\n } else {\n this.currentFilters = fieldOrFilters;\n }\n this.applyFilters();\n this.fire('filter', this, this.currentFilters);\n }\n\n clearFilter(suppressEvent?: boolean): void {\n this.currentFilters = [];\n this.applyFilters();\n if (!suppressEvent) {\n this.fire('filter', this, []);\n }\n }\n\n getFilters(): Filter[] {\n return [...this.currentFilters];\n }\n\n private applyFilters(): void {\n if (this.currentFilters.length === 0) {\n // Restore all data\n this.data = new Collection<Model>((r) => r.getId());\n this.allData.each((r) => this.data.add(r));\n } else {\n this.data = new Collection<Model>((r) => r.getId());\n this.allData.each((r) => {\n const passes = this.currentFilters.every((f) => matchFilter(r, f));\n if (passes) this.data.add(r);\n });\n }\n\n // Re-apply sort if active\n if (this.currentSorters.length > 0) {\n this.data.sort(buildComparator(this.currentSorters));\n }\n\n this.invalidateGroups();\n }\n\n // -----------------------------------------------------------------------\n // Grouping\n // -----------------------------------------------------------------------\n\n group(field: string, direction: 'ASC' | 'DESC' = 'ASC'): void {\n this.groupField = field;\n this.groupDirection = direction;\n this.invalidateGroups();\n this.fire('groupchange', this, field, direction);\n }\n\n clearGrouping(): void {\n this.groupField = null;\n this.cachedGroups = null;\n this.fire('groupchange', this, null, null);\n }\n\n isGrouped(): boolean {\n return this.groupField !== null;\n }\n\n getGroups(): Group[] {\n if (!this.groupField) return [];\n if (this.cachedGroups) return this.cachedGroups;\n\n const map = new Map<string, Model[]>();\n this.data.each((r) => {\n const key = String(r.get(this.groupField!) ?? '');\n if (!map.has(key)) map.set(key, []);\n map.get(key)!.push(r);\n });\n\n const groups = [...map.entries()].map(([name, children]) => ({ name, children }));\n const dir = this.groupDirection === 'DESC' ? -1 : 1;\n groups.sort((a, b) => {\n if (a.name < b.name) return -1 * dir;\n if (a.name > b.name) return 1 * dir;\n return 0;\n });\n\n this.cachedGroups = groups;\n return groups;\n }\n\n private invalidateGroups(): void {\n this.cachedGroups = null;\n }\n\n // -----------------------------------------------------------------------\n // Sync / change tracking\n // -----------------------------------------------------------------------\n\n getModifiedRecords(): Model[] {\n const result: Model[] = [];\n this.data.each((r) => {\n if (r.isModified()) result.push(r);\n });\n return result;\n }\n\n getNewRecords(): Model[] {\n const result: Model[] = [];\n this.data.each((r) => {\n if (r.phantom) result.push(r);\n });\n return result;\n }\n\n getRemovedRecords(): Model[] {\n return [...this.removedRecords];\n }\n\n commitChanges(): void {\n this.data.each((r) => {\n if (r.isModified()) r.commit(true);\n });\n this.removedRecords.length = 0;\n }\n\n rejectChanges(): void {\n // Revert modified records\n this.data.each((r) => {\n if (r.isModified()) r.reject(true);\n });\n\n // Re-add removed records\n for (const record of this.removedRecords) {\n this.data.add(record);\n this.allData.add(record);\n }\n this.removedRecords.length = 0;\n this.invalidateGroups();\n }\n\n // -----------------------------------------------------------------------\n // Event helper\n // -----------------------------------------------------------------------\n\n private fire(eventName: string, ...args: unknown[]): void {\n if (typeof (this as any).fireEvent === 'function') {\n (this as any).fireEvent(eventName, ...args);\n }\n }\n}\n","/**\n * @framesquared/data – Collection\n *\n * An ordered, optionally keyed collection used internally by Store.\n * Provides add, insert, remove, sort, find, and iteration.\n */\n\nexport class Collection<T> {\n private items: T[] = [];\n private keyMap: Map<unknown, T> | null = null;\n private keyFn: ((item: T) => unknown) | undefined;\n\n constructor(keyFn?: (item: T) => unknown) {\n this.keyFn = keyFn;\n if (keyFn) {\n this.keyMap = new Map();\n }\n }\n\n getCount(): number {\n return this.items.length;\n }\n\n getAt(index: number): T | undefined {\n return this.items[index];\n }\n\n getByKey(key: unknown): T | undefined {\n return this.keyMap?.get(key);\n }\n\n indexOf(item: T): number {\n return this.items.indexOf(item);\n }\n\n contains(item: T): boolean {\n return this.items.includes(item);\n }\n\n add(item: T): void {\n this.items.push(item);\n if (this.keyFn && this.keyMap) {\n this.keyMap.set(this.keyFn(item), item);\n }\n }\n\n insert(index: number, item: T): void {\n this.items.splice(index, 0, item);\n if (this.keyFn && this.keyMap) {\n this.keyMap.set(this.keyFn(item), item);\n }\n }\n\n remove(item: T): T | undefined {\n const idx = this.items.indexOf(item);\n if (idx === -1) return undefined;\n this.items.splice(idx, 1);\n if (this.keyFn && this.keyMap) {\n this.keyMap.delete(this.keyFn(item));\n }\n return item;\n }\n\n removeAt(index: number, count = 1): T[] {\n const removed = this.items.splice(index, count);\n if (this.keyFn && this.keyMap) {\n for (const item of removed) {\n this.keyMap.delete(this.keyFn(item));\n }\n }\n return removed;\n }\n\n clear(): void {\n this.items.length = 0;\n this.keyMap?.clear();\n }\n\n toArray(): T[] {\n return [...this.items];\n }\n\n each(fn: (item: T, index: number) => boolean | void): void {\n for (let i = 0; i < this.items.length; i++) {\n if (fn(this.items[i], i) === false) break;\n }\n }\n\n find(fn: (item: T) => boolean): T | undefined {\n return this.items.find(fn);\n }\n\n filter(fn: (item: T) => boolean): T[] {\n return this.items.filter(fn);\n }\n\n sort(compareFn: (a: T, b: T) => number): void {\n this.items.sort(compareFn);\n }\n\n first(): T | undefined {\n return this.items[0];\n }\n\n last(): T | undefined {\n return this.items[this.items.length - 1];\n }\n\n getRange(start = 0, end?: number): T[] {\n return this.items.slice(start, end);\n }\n\n /** Rebuilds the key map (call after sort or external mutation). */\n rekey(): void {\n if (this.keyFn && this.keyMap) {\n this.keyMap.clear();\n for (const item of this.items) {\n this.keyMap.set(this.keyFn(item), item);\n }\n }\n }\n}\n","/**\n * @framesquared/data – ResultSet\n */\n\nimport type { Model } from './Model.js';\n\nexport interface ResultSetConfig {\n records: Model[];\n total?: number;\n success: boolean;\n message?: string;\n}\n\nexport class ResultSet {\n readonly records: Model[];\n readonly total: number;\n readonly success: boolean;\n readonly message: string | undefined;\n\n constructor(config: ResultSetConfig) {\n this.records = config.records;\n this.total = config.total ?? config.records.length;\n this.success = config.success;\n this.message = config.message;\n }\n}\n","/**\n * @framesquared/data – Readers\n *\n * Parse raw server response data into ResultSet instances.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { Model } from '../Model.js';\nimport { ResultSet } from '../ResultSet.js';\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction getNestedValue(obj: any, path: string): unknown {\n const segments = path.split('.');\n let current: any = obj;\n for (const seg of segments) {\n if (current == null || typeof current !== 'object') return undefined;\n current = current[seg];\n }\n return current;\n}\n\n// ---------------------------------------------------------------------------\n// JsonReader\n// ---------------------------------------------------------------------------\n\nexport interface JsonReaderConfig {\n model: typeof Model;\n rootProperty?: string;\n totalProperty?: string;\n successProperty?: string;\n messageProperty?: string;\n}\n\nexport class JsonReader {\n protected config: JsonReaderConfig;\n\n constructor(config: JsonReaderConfig) {\n this.config = config;\n }\n\n read(data: unknown): ResultSet {\n const { model, rootProperty, totalProperty, successProperty, messageProperty } = this.config;\n\n let rawRecords: any[];\n let total: number | undefined;\n let success = true;\n let message: string | undefined;\n\n if (rootProperty) {\n const root = getNestedValue(data, rootProperty);\n rawRecords = Array.isArray(root) ? root : [];\n } else {\n rawRecords = Array.isArray(data) ? data : [];\n }\n\n if (totalProperty && typeof data === 'object' && data !== null) {\n const t = getNestedValue(data, totalProperty);\n if (typeof t === 'number') total = t;\n }\n\n if (successProperty && typeof data === 'object' && data !== null) {\n const s = getNestedValue(data, successProperty);\n if (typeof s === 'boolean') success = s;\n }\n\n if (messageProperty && typeof data === 'object' && data !== null) {\n const m = getNestedValue(data, messageProperty);\n if (typeof m === 'string') message = m;\n }\n\n const records = rawRecords.map((raw) => model.create(raw));\n return new ResultSet({\n records,\n total: total ?? records.length,\n success,\n message,\n });\n }\n}\n\n// ---------------------------------------------------------------------------\n// ArrayReader\n// ---------------------------------------------------------------------------\n\nexport interface ArrayReaderConfig {\n model: typeof Model;\n}\n\nexport class ArrayReader {\n private config: ArrayReaderConfig;\n\n constructor(config: ArrayReaderConfig) {\n this.config = config;\n }\n\n read(data: unknown[][]): ResultSet {\n const { model } = this.config;\n const fieldNames = (model as any).fields.map((f: any) =>\n typeof f === 'string' ? f : f.name,\n ) as string[];\n\n const records = data.map((row) => {\n const obj: Record<string, unknown> = {};\n for (let i = 0; i < fieldNames.length; i++) {\n if (i < row.length) {\n obj[fieldNames[i]] = row[i];\n }\n }\n return model.create(obj);\n });\n\n return new ResultSet({ records, success: true });\n }\n}\n\n// ---------------------------------------------------------------------------\n// XmlReader\n// ---------------------------------------------------------------------------\n\nexport interface XmlReaderConfig {\n model: typeof Model;\n record: string;\n}\n\nexport class XmlReader {\n private config: XmlReaderConfig;\n\n constructor(config: XmlReaderConfig) {\n this.config = config;\n }\n\n read(xmlString: string): ResultSet {\n const { model, record: tagName } = this.config;\n const parser = new DOMParser();\n const doc = parser.parseFromString(xmlString, 'text/xml');\n const nodes = doc.getElementsByTagName(tagName);\n\n const fieldNames = (model as any).fields.map((f: any) =>\n typeof f === 'string' ? f : f.name,\n ) as string[];\n\n const records: Model[] = [];\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n const obj: Record<string, unknown> = {};\n for (const fieldName of fieldNames) {\n // Try exact tag match first, then first-letter tag ('n' for 'name')\n let el = node.getElementsByTagName(fieldName)[0];\n if (!el) {\n // Fallback: try single-char abbreviation\n el = node.getElementsByTagName(fieldName[0])[0] as Element;\n }\n if (el) {\n obj[fieldName] = el.textContent ?? '';\n }\n }\n records.push(model.create(obj));\n }\n\n return new ResultSet({ records, success: true });\n }\n}\n","/**\n * @framesquared/data – Writers\n *\n * Serialize Model records for transport to the server.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { Model } from '../Model.js';\n\n// ---------------------------------------------------------------------------\n// JsonWriter\n// ---------------------------------------------------------------------------\n\nexport interface JsonWriterConfig {\n writeAllFields?: boolean;\n allowSingle?: boolean;\n encode?: boolean;\n rootProperty?: string;\n}\n\nexport class JsonWriter {\n private config: JsonWriterConfig;\n\n constructor(config: JsonWriterConfig) {\n this.config = {\n writeAllFields: true,\n allowSingle: false,\n encode: false,\n ...config,\n };\n }\n\n write(records: Model[]): unknown {\n const serialized = records.map((r) => this.serializeRecord(r));\n\n let result: unknown;\n\n // allowSingle: unwrap single-element array\n if (this.config.allowSingle && serialized.length === 1) {\n result = serialized[0];\n } else {\n result = serialized;\n }\n\n // rootProperty: wrap under a key\n if (this.config.rootProperty) {\n result = { [this.config.rootProperty]: result };\n }\n\n // encode: convert to JSON string\n if (this.config.encode) {\n return JSON.stringify(result);\n }\n\n return result;\n }\n\n private serializeRecord(record: Model): Record<string, unknown> {\n if (this.config.writeAllFields) {\n return record.getData({ serialize: true });\n }\n\n // writeAllFields=false: only send changed fields + id\n const Ctor = record.constructor as typeof Model;\n const changes = record.getChanges();\n const result: Record<string, unknown> = {};\n\n // Always include the ID\n const idProp = Ctor.idProperty;\n result[idProp] = record.get(idProp);\n\n // Add changed fields\n for (const [key, value] of Object.entries(changes)) {\n result[key] = value;\n }\n\n return result;\n }\n}\n\n// ---------------------------------------------------------------------------\n// XmlWriter\n// ---------------------------------------------------------------------------\n\nexport interface XmlWriterConfig {\n documentRoot?: string;\n record?: string;\n}\n\nexport class XmlWriter {\n private config: XmlWriterConfig;\n\n constructor(config: XmlWriterConfig) {\n this.config = {\n documentRoot: 'xmlData',\n record: 'record',\n ...config,\n };\n }\n\n write(records: Model[]): string {\n const root = this.config.documentRoot!;\n const tag = this.config.record!;\n const parts: string[] = [`<${root}>`];\n\n for (const record of records) {\n parts.push(`<${tag}>`);\n const data = record.getData({ serialize: true });\n for (const [key, value] of Object.entries(data)) {\n parts.push(`<${key}>${escapeXml(String(value ?? ''))}</${key}>`);\n }\n parts.push(`</${tag}>`);\n }\n\n parts.push(`</${root}>`);\n return parts.join('');\n }\n}\n\nfunction escapeXml(str: string): string {\n return str\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&apos;');\n}\n","/**\n * @framesquared/data – Proxy (abstract base)\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { Model } from '../Model.js';\nimport type { Operation } from '../Operation.js';\nimport { ResultSet } from '../ResultSet.js';\n\nexport interface BatchOptions {\n create?: Model[];\n update?: Model[];\n destroy?: Model[];\n}\n\nexport interface Batch {\n success: boolean;\n operations: Operation[];\n}\n\nexport interface ProxyConfig {\n model: typeof Model;\n [key: string]: unknown;\n}\n\nexport abstract class Proxy {\n readonly model: typeof Model;\n\n constructor(config: ProxyConfig) {\n this.model = config.model;\n }\n\n abstract read(operation: Operation, signal?: AbortSignal): Promise<ResultSet>;\n abstract create(operation: Operation): Promise<ResultSet>;\n abstract update(operation: Operation): Promise<ResultSet>;\n abstract destroy(operation: Operation): Promise<ResultSet>;\n\n async batch(options: BatchOptions): Promise<Batch> {\n const { Operation: OpClass } = await import('../Operation.js');\n const operations: Operation[] = [];\n let allSuccess = true;\n\n if (options.create && options.create.length > 0) {\n const op = new OpClass({ action: 'create', records: options.create });\n const rs = await this.create(op);\n op.setResult(rs);\n operations.push(op);\n if (!rs.success) allSuccess = false;\n }\n\n if (options.update && options.update.length > 0) {\n const op = new OpClass({ action: 'update', records: options.update });\n const rs = await this.update(op);\n op.setResult(rs);\n operations.push(op);\n if (!rs.success) allSuccess = false;\n }\n\n if (options.destroy && options.destroy.length > 0) {\n const op = new OpClass({ action: 'destroy', records: options.destroy });\n const rs = await this.destroy(op);\n op.setResult(rs);\n operations.push(op);\n if (!rs.success) allSuccess = false;\n }\n\n return { success: allSuccess, operations };\n }\n}\n","/**\n * @framesquared/data – Client Proxies\n *\n * MemoryProxy, LocalStorageProxy, SessionStorageProxy\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { Operation } from '../Operation.js';\nimport { ResultSet } from '../ResultSet.js';\nimport { Proxy } from './Proxy.js';\nimport type { ProxyConfig } from './Proxy.js';\n\n// ---------------------------------------------------------------------------\n// MemoryProxy\n// ---------------------------------------------------------------------------\n\nexport interface MemoryProxyConfig extends ProxyConfig {\n data?: Record<string, unknown>[];\n}\n\nexport class MemoryProxy extends Proxy {\n private store: Record<string, unknown>[];\n\n constructor(config: MemoryProxyConfig) {\n super(config);\n this.store = config.data ? [...config.data] : [];\n }\n\n async read(operation: Operation): Promise<ResultSet> {\n let data = [...this.store];\n\n // Local filtering\n if (operation.filters && operation.filters.length > 0) {\n data = data.filter((raw) => {\n return operation.filters!.every((f: any) => {\n const fieldVal = raw[f.property];\n const op = f.operator ?? '=';\n switch (op) {\n case '=': return fieldVal === f.value;\n case '!=': return fieldVal !== f.value;\n case '<': return (fieldVal as number) < f.value;\n case '<=': return (fieldVal as number) <= f.value;\n case '>': return (fieldVal as number) > f.value;\n case '>=': return (fieldVal as number) >= f.value;\n default: return true;\n }\n });\n });\n }\n\n // Local sorting\n if (operation.sorters && operation.sorters.length > 0) {\n data.sort((a, b) => {\n for (const sorter of operation.sorters!) {\n const va = a[sorter.property] as string | number;\n const vb = b[sorter.property] as string | number;\n const dir = sorter.direction === 'DESC' ? -1 : 1;\n if (va < vb) return -1 * dir;\n if (va > vb) return 1 * dir;\n }\n return 0;\n });\n }\n\n const total = data.length;\n\n // Local paging\n if (operation.start !== undefined || operation.limit !== undefined) {\n const start = operation.start ?? 0;\n const limit = operation.limit ?? data.length;\n data = data.slice(start, start + limit);\n }\n\n const records = data.map((raw) => this.model.create(raw));\n return new ResultSet({ records, total, success: true });\n }\n\n async create(operation: Operation): Promise<ResultSet> {\n for (const record of operation.records) {\n this.store.push(record.getData());\n }\n return new ResultSet({ records: operation.records, success: true });\n }\n\n async update(operation: Operation): Promise<ResultSet> {\n for (const record of operation.records) {\n const id = record.getId();\n const idProp = (this.model as any).idProperty ?? 'id';\n const idx = this.store.findIndex((r) => r[idProp] === id);\n if (idx !== -1) {\n this.store[idx] = record.getData();\n }\n }\n return new ResultSet({ records: operation.records, success: true });\n }\n\n async destroy(operation: Operation): Promise<ResultSet> {\n for (const record of operation.records) {\n const id = record.getId();\n const idProp = (this.model as any).idProperty ?? 'id';\n const idx = this.store.findIndex((r) => r[idProp] === id);\n if (idx !== -1) {\n this.store.splice(idx, 1);\n }\n }\n return new ResultSet({ records: operation.records, success: true });\n }\n}\n\n// ---------------------------------------------------------------------------\n// WebStorageProxy (shared logic for localStorage / sessionStorage)\n// ---------------------------------------------------------------------------\n\nexport interface WebStorageProxyConfig extends ProxyConfig {\n id: string;\n}\n\nabstract class WebStorageProxy extends Proxy {\n protected storageId: string;\n protected abstract getStorage(): Storage;\n\n constructor(config: WebStorageProxyConfig) {\n super(config);\n this.storageId = config.id;\n }\n\n private loadAll(): Record<string, unknown>[] {\n const raw = this.getStorage().getItem(this.storageId);\n if (!raw) return [];\n try {\n return JSON.parse(raw) as Record<string, unknown>[];\n } catch {\n return [];\n }\n }\n\n private saveAll(data: Record<string, unknown>[]): void {\n this.getStorage().setItem(this.storageId, JSON.stringify(data));\n }\n\n async read(_operation: Operation): Promise<ResultSet> {\n const data = this.loadAll();\n const records = data.map((raw) => this.model.create(raw));\n return new ResultSet({ records, success: true });\n }\n\n async create(operation: Operation): Promise<ResultSet> {\n const data = this.loadAll();\n for (const record of operation.records) {\n data.push(record.getData({ serialize: true }));\n }\n this.saveAll(data);\n return new ResultSet({ records: operation.records, success: true });\n }\n\n async update(operation: Operation): Promise<ResultSet> {\n const data = this.loadAll();\n const idProp = (this.model as any).idProperty ?? 'id';\n for (const record of operation.records) {\n const id = record.getId();\n const idx = data.findIndex((r) => r[idProp] === id);\n if (idx !== -1) {\n data[idx] = record.getData({ serialize: true });\n }\n }\n this.saveAll(data);\n return new ResultSet({ records: operation.records, success: true });\n }\n\n async destroy(operation: Operation): Promise<ResultSet> {\n let data = this.loadAll();\n const idProp = (this.model as any).idProperty ?? 'id';\n for (const record of operation.records) {\n const id = record.getId();\n data = data.filter((r) => r[idProp] !== id);\n }\n this.saveAll(data);\n return new ResultSet({ records: operation.records, success: true });\n }\n}\n\n// ---------------------------------------------------------------------------\n// LocalStorageProxy\n// ---------------------------------------------------------------------------\n\nexport class LocalStorageProxy extends WebStorageProxy {\n protected getStorage(): Storage {\n return localStorage;\n }\n}\n\n// ---------------------------------------------------------------------------\n// SessionStorageProxy\n// ---------------------------------------------------------------------------\n\nexport class SessionStorageProxy extends WebStorageProxy {\n protected getStorage(): Storage {\n return sessionStorage;\n }\n}\n","/**\n * @framesquared/data – Server Proxies\n *\n * AjaxProxy (fetch-based) and RestProxy (RESTful URL patterns).\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { Operation } from '../Operation.js';\nimport { ResultSet } from '../ResultSet.js';\nimport { JsonReader } from '../reader/Reader.js';\nimport { JsonWriter } from '../writer/Writer.js';\nimport { Proxy } from './Proxy.js';\nimport type { ProxyConfig } from './Proxy.js';\n\n// ---------------------------------------------------------------------------\n// AjaxProxy\n// ---------------------------------------------------------------------------\n\nexport interface AjaxProxyConfig extends ProxyConfig {\n url: string;\n api?: Partial<Record<string, string>>;\n headers?: Record<string, string>;\n timeout?: number;\n withCredentials?: boolean;\n}\n\nconst ACTION_METHODS: Record<string, string> = {\n read: 'GET',\n create: 'POST',\n update: 'PUT',\n destroy: 'DELETE',\n};\n\nexport class AjaxProxy extends Proxy {\n protected url: string;\n protected api: Partial<Record<string, string>>;\n protected headers: Record<string, string>;\n protected timeout: number;\n protected withCredentials: boolean;\n protected reader: JsonReader;\n protected writer: JsonWriter;\n\n constructor(config: AjaxProxyConfig) {\n super(config);\n this.url = config.url;\n this.api = config.api ?? {};\n this.headers = config.headers ?? {};\n this.timeout = config.timeout ?? 30000;\n this.withCredentials = config.withCredentials ?? false;\n this.reader = new JsonReader({ model: config.model });\n this.writer = new JsonWriter({});\n }\n\n async read(operation: Operation, signal?: AbortSignal): Promise<ResultSet> {\n return this.doRequest(operation, 'read', signal);\n }\n\n async create(operation: Operation): Promise<ResultSet> {\n return this.doRequest(operation, 'create');\n }\n\n async update(operation: Operation): Promise<ResultSet> {\n return this.doRequest(operation, 'update');\n }\n\n async destroy(operation: Operation): Promise<ResultSet> {\n return this.doRequest(operation, 'destroy');\n }\n\n protected buildUrl(operation: Operation, action: string): string {\n const base = this.api[action] ?? this.url;\n const params = { ...operation.params };\n\n // Add paging params\n if (operation.start !== undefined) params.start = operation.start;\n if (operation.limit !== undefined) params.limit = operation.limit;\n if (operation.page !== undefined) params.page = operation.page;\n\n const qs = Object.entries(params)\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`)\n .join('&');\n\n return qs ? `${base}?${qs}` : base;\n }\n\n protected async doRequest(\n operation: Operation,\n action: string,\n signal?: AbortSignal,\n ): Promise<ResultSet> {\n const method = ACTION_METHODS[action] ?? 'GET';\n const url = this.buildUrl(operation, action);\n\n const init: RequestInit = {\n method,\n headers: {\n 'Content-Type': 'application/json',\n ...this.headers,\n },\n credentials: this.withCredentials ? 'include' : 'same-origin',\n signal,\n };\n\n if (method !== 'GET' && operation.records.length > 0) {\n init.body = JSON.stringify(this.writer.write(operation.records));\n }\n\n try {\n const response = await fetch(url, init);\n\n if (!response.ok) {\n let message = `HTTP ${response.status}`;\n try {\n const body = await response.json();\n if (body?.message) message = body.message;\n } catch { /* ignore */ }\n return new ResultSet({ records: [], success: false, message });\n }\n\n const data = await response.json();\n\n // For read, parse through reader\n if (action === 'read') {\n return this.reader.read(data);\n }\n\n // For CUD, build a simple result\n const records = Array.isArray(data)\n ? data.map((d: any) => this.model.create(d))\n : data && typeof data === 'object' && 'id' in data\n ? [this.model.create(data)]\n : operation.records;\n\n return new ResultSet({ records, success: true });\n } catch (err: any) {\n return new ResultSet({\n records: [],\n success: false,\n message: err?.message ?? 'Unknown error',\n });\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// RestProxy\n// ---------------------------------------------------------------------------\n\nexport interface RestProxyConfig extends AjaxProxyConfig {\n appendId?: boolean;\n}\n\nexport class RestProxy extends AjaxProxy {\n private appendId: boolean;\n\n constructor(config: RestProxyConfig) {\n super(config);\n this.appendId = config.appendId ?? true;\n }\n\n protected override buildUrl(operation: Operation, action: string): string {\n let base = this.api[action] ?? this.url;\n\n // Append record ID for single-record operations\n if (this.appendId && action !== 'create' && operation.records.length === 1) {\n const id = operation.records[0].getId();\n if (id !== undefined && id !== null && id !== 0 && id !== '') {\n base = `${base}/${id}`;\n }\n }\n\n // Add query params for read\n const params = { ...operation.params };\n if (operation.start !== undefined) params.start = operation.start;\n if (operation.limit !== undefined) params.limit = operation.limit;\n if (operation.page !== undefined) params.page = operation.page;\n\n const qs = Object.entries(params)\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`)\n .join('&');\n\n return qs ? `${base}?${qs}` : base;\n }\n}\n","/**\n * @framesquared/data – TreeStore\n *\n * Manages hierarchical (tree) data. Records are enhanced with\n * NodeInterface for parent/child navigation, expand/collapse,\n * and nested serialization.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { Base, Observable } from '@framesquared/core';\nimport type { Model } from '../Model.js';\nimport { TreeModel } from '../model/TreeModel.js';\nimport { applyNodeInterface } from '../mixin/NodeInterface.js';\nimport type { NodeInterface } from '../mixin/NodeInterface.js';\n\n// ---------------------------------------------------------------------------\n// Observable bootstrap\n// ---------------------------------------------------------------------------\n\nconst ObservableMixin: typeof Base = Observable;\n\nfunction ensureObservable(instance: any): void {\n const proto = ObservableMixin.prototype;\n for (const name of Object.getOwnPropertyNames(proto)) {\n if (name === 'constructor') continue;\n if (name in instance) continue;\n const desc = Object.getOwnPropertyDescriptor(proto, name);\n if (desc && typeof desc.value === 'function') {\n instance[name] = desc.value.bind(instance);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Config\n// ---------------------------------------------------------------------------\n\nexport interface TreeStoreConfig {\n model?: typeof Model;\n root?: Record<string, unknown>;\n proxy?: any;\n}\n\n// ---------------------------------------------------------------------------\n// TreeStore\n// ---------------------------------------------------------------------------\n\nexport class TreeStore extends Base {\n static override $className = 'Ext.data.TreeStore';\n\n private ModelClass: typeof Model;\n private rootNode!: NodeInterface;\n private nodeMap = new Map<string | number, NodeInterface>();\n\n $destroyHooks: (() => void)[] = [];\n\n constructor(config: TreeStoreConfig) {\n super();\n ensureObservable(this);\n\n this.ModelClass = config.model ?? TreeModel;\n\n if (config.root) {\n this.replaceRoot(this.buildNode(config.root, 0));\n } else {\n // Create an empty root\n const empty = this.ModelClass.create({ id: '__root__', text: 'Root' });\n applyNodeInterface(empty, 0);\n this.replaceRoot(empty as any as NodeInterface);\n }\n }\n\n // -----------------------------------------------------------------------\n // Root\n // -----------------------------------------------------------------------\n\n getRoot(): NodeInterface {\n return this.rootNode;\n }\n\n getRootNode(): NodeInterface {\n return this.rootNode;\n }\n\n /**\n * Replaces the root with new data (or a pre-built node).\n * Fires 'rootchange'.\n */\n setRoot(nodeOrData: NodeInterface | Record<string, unknown>): NodeInterface {\n let node: NodeInterface;\n if (this.isNodeInterface(nodeOrData)) {\n node = nodeOrData;\n } else {\n node = this.buildNode(nodeOrData as Record<string, unknown>, 0);\n }\n this.replaceRoot(node);\n return node;\n }\n\n private isNodeInterface(value: unknown): value is NodeInterface {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'childNodes' in value &&\n 'parentNode' in value &&\n typeof (value as NodeInterface).isRoot === 'function'\n );\n }\n\n private replaceRoot(node: NodeInterface): void {\n this.rootNode = node;\n this.nodeMap.clear();\n this.registerRecursive(node);\n this.fire('rootchange', this, node);\n }\n\n // -----------------------------------------------------------------------\n // Lookup\n // -----------------------------------------------------------------------\n\n getNodeById(id: string | number): NodeInterface | undefined {\n return this.nodeMap.get(id);\n }\n\n // -----------------------------------------------------------------------\n // Tree operations\n // -----------------------------------------------------------------------\n\n appendChild(parent: NodeInterface, child: NodeInterface): void {\n parent.appendChild(child);\n this.registerRecursive(child);\n this.fire('nodeappend', this, child, parent);\n this.fire('datachanged', this);\n }\n\n removeChild(parent: NodeInterface, child: NodeInterface): void {\n parent.removeChild(child);\n this.unregisterRecursive(child);\n this.fire('noderemove', this, child, parent);\n this.fire('datachanged', this);\n }\n\n insertBefore(node: NodeInterface, refNode: NodeInterface): void {\n const parent = refNode.parentNode;\n if (!parent) return;\n parent.insertBefore(node, refNode);\n this.registerRecursive(node);\n this.fire('nodeinsert', this, node, refNode, parent);\n this.fire('datachanged', this);\n }\n\n // -----------------------------------------------------------------------\n // Expand / Collapse\n // -----------------------------------------------------------------------\n\n expandNode(node: NodeInterface): void {\n node.expanded = true;\n node.loaded = true;\n this.fire('nodeexpand', this, node);\n }\n\n collapseNode(node: NodeInterface): void {\n node.expanded = false;\n this.fire('nodecollapse', this, node);\n }\n\n // -----------------------------------------------------------------------\n // Deep search\n // -----------------------------------------------------------------------\n\n findNode(field: string, value: unknown): NodeInterface | undefined {\n return this.findNodeImpl(this.rootNode, field, value);\n }\n\n private findNodeImpl(\n node: NodeInterface,\n field: string,\n value: unknown,\n ): NodeInterface | undefined {\n const model = node as any as { get(f: string): unknown; getId(): unknown };\n const nodeValue = field === 'id' ? model.getId() : model.get(field);\n if (nodeValue === value) return node;\n for (const child of node.childNodes) {\n const found = this.findNodeImpl(child, field, value);\n if (found) return found;\n }\n return undefined;\n }\n\n // -----------------------------------------------------------------------\n // Collapse / Expand all\n // -----------------------------------------------------------------------\n\n collapseAll(): void {\n this.rootNode.cascadeBy((node) => {\n node.expanded = false;\n });\n }\n\n expandAll(): void {\n this.rootNode.cascadeBy((node) => {\n node.expanded = true;\n });\n }\n\n // -----------------------------------------------------------------------\n // Count helpers\n // -----------------------------------------------------------------------\n\n getCount(): number {\n return this.flattenNodes().length;\n }\n\n getTotalCount(): number {\n return this.nodeMap.size;\n }\n\n // -----------------------------------------------------------------------\n // Flatten (for rendering in a flat list / grid)\n // -----------------------------------------------------------------------\n\n flattenNodes(): Model[] {\n const result: Model[] = [];\n this.flattenWalk(this.rootNode, result);\n return result;\n }\n\n private flattenWalk(node: NodeInterface, out: Model[]): void {\n out.push(node as any as Model);\n if (node.expanded || node.isRoot()) {\n for (const child of node.childNodes) {\n this.flattenWalk(child, out);\n }\n }\n }\n\n // -----------------------------------------------------------------------\n // Build tree from nested data\n // -----------------------------------------------------------------------\n\n private buildNode(data: Record<string, unknown>, depth: number): NodeInterface {\n const children = data.children as Record<string, unknown>[] | undefined;\n const expanded = data.expanded as boolean | undefined;\n const nodeData = { ...data };\n delete nodeData.children;\n delete nodeData.expanded;\n\n const model = this.ModelClass.create(nodeData);\n applyNodeInterface(model, depth);\n const node = model as any as NodeInterface;\n\n if (expanded) {\n node.expanded = true;\n node.loaded = true;\n }\n\n if (children && Array.isArray(children)) {\n for (const childData of children) {\n const childNode = this.buildNode(childData, depth + 1);\n node.appendChild(childNode);\n }\n node.loaded = true;\n }\n\n return node;\n }\n\n // -----------------------------------------------------------------------\n // Node registration (for id-based lookup)\n // -----------------------------------------------------------------------\n\n private registerRecursive(node: NodeInterface): void {\n const id = (node as any as Model).getId();\n if (id !== undefined && id !== null) {\n this.nodeMap.set(id, node);\n }\n for (const child of node.childNodes) {\n this.registerRecursive(child);\n }\n }\n\n private unregisterRecursive(node: NodeInterface): void {\n const id = (node as any as Model).getId();\n if (id !== undefined && id !== null) {\n this.nodeMap.delete(id);\n }\n for (const child of node.childNodes) {\n this.unregisterRecursive(child);\n }\n }\n\n // -----------------------------------------------------------------------\n // Event helper\n // -----------------------------------------------------------------------\n\n private fire(eventName: string, ...args: unknown[]): void {\n if (typeof (this as any).fireEvent === 'function') {\n (this as any).fireEvent(eventName, ...args);\n }\n }\n}\n","/**\n * @framesquared/data – NodeInterface\n *\n * Mixin applied to Model instances to give them tree-node capabilities:\n * parent/child/sibling navigation, depth, expand/collapse state,\n * cascadeBy, bubble, getPath, findChild, sort, and nested serialization.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { Model } from '../Model.js';\nimport type { Sorter } from '../store/Store.js';\n\n// ---------------------------------------------------------------------------\n// NodeInterface\n// ---------------------------------------------------------------------------\n\nexport interface NodeInterface extends Model {\n parentNode: NodeInterface | null;\n childNodes: NodeInterface[];\n firstChild: NodeInterface | null;\n lastChild: NodeInterface | null;\n previousSibling: NodeInterface | null;\n nextSibling: NodeInterface | null;\n depth: number;\n\n /** Node state */\n expanded: boolean;\n loaded: boolean;\n\n isLeaf(): boolean;\n isRoot(): boolean;\n isExpanded(): boolean;\n isLoaded(): boolean;\n\n appendChild(child: NodeInterface): void;\n removeChild(child: NodeInterface): void;\n insertBefore(newChild: NodeInterface, refChild: NodeInterface): void;\n\n getPath(separator?: string): string;\n cascadeBy(fn: (node: NodeInterface) => boolean | void): void;\n bubble(fn: (node: NodeInterface) => boolean | void): void;\n contains(child: NodeInterface): boolean;\n findChild(field: string, value: unknown, deep?: boolean): NodeInterface | undefined;\n sort(sorters: Sorter[]): void;\n serialize(): any;\n\n // Extended methods\n eachChild(fn: (child: NodeInterface, index: number) => boolean | void, scope?: object): void;\n indexOf(child: NodeInterface): number;\n getChildAt(index: number): NodeInterface | undefined;\n childCount(): number;\n hasChildNodes(): boolean;\n getChildren(deep?: boolean): NodeInterface[];\n findChildBy(predicate: (node: NodeInterface) => boolean | void, deep?: boolean): NodeInterface | undefined;\n removeAll(): NodeInterface[];\n copy(deep?: boolean): NodeInterface;\n getDepth(): number;\n}\n\n// ---------------------------------------------------------------------------\n// applyNodeInterface — attaches node methods/properties to a model\n// ---------------------------------------------------------------------------\n\nexport function applyNodeInterface(model: Model, depth = 0): void {\n const node = model as any as NodeInterface;\n\n // Properties\n node.parentNode = node.parentNode ?? null;\n node.childNodes = node.childNodes ?? [];\n node.firstChild = node.firstChild ?? null;\n node.lastChild = node.lastChild ?? null;\n node.previousSibling = node.previousSibling ?? null;\n node.nextSibling = node.nextSibling ?? null;\n node.depth = depth;\n node.expanded = node.expanded ?? false;\n node.loaded = node.loaded ?? false;\n\n // Methods\n node.isLeaf = function (): boolean {\n // Explicitly marked as leaf, OR has no children\n if (this.get('leaf') === true) return true;\n return this.childNodes.length === 0;\n };\n\n node.isRoot = function (): boolean {\n return this.parentNode === null;\n };\n\n node.isExpanded = function (): boolean {\n return this.expanded;\n };\n\n node.isLoaded = function (): boolean {\n return this.loaded;\n };\n\n node.appendChild = function (child: NodeInterface): void {\n const c = child as any as NodeInterface;\n\n // Remove from current parent if any\n if (c.parentNode) {\n c.parentNode.removeChild(c);\n }\n\n c.parentNode = this;\n c.depth = this.depth + 1;\n\n const children = this.childNodes;\n const prevLast = children.length > 0 ? children[children.length - 1] : null;\n\n children.push(c);\n\n // Update sibling links\n if (prevLast) {\n prevLast.nextSibling = c;\n c.previousSibling = prevLast;\n } else {\n c.previousSibling = null;\n }\n c.nextSibling = null;\n\n // Update first/last\n this.firstChild = children[0];\n this.lastChild = children[children.length - 1];\n\n // Update depth recursively\n updateDepthRecursive(c, this.depth + 1);\n };\n\n node.removeChild = function (child: NodeInterface): void {\n const children = this.childNodes;\n const idx = children.indexOf(child);\n if (idx === -1) return;\n\n children.splice(idx, 1);\n\n // Update sibling links\n if (child.previousSibling) {\n child.previousSibling.nextSibling = child.nextSibling;\n }\n if (child.nextSibling) {\n child.nextSibling.previousSibling = child.previousSibling;\n }\n\n child.parentNode = null;\n child.previousSibling = null;\n child.nextSibling = null;\n\n // Update first/last\n this.firstChild = children.length > 0 ? children[0] : null;\n this.lastChild = children.length > 0 ? children[children.length - 1] : null;\n };\n\n node.insertBefore = function (newChild: NodeInterface, refChild: NodeInterface): void {\n const children = this.childNodes;\n const refIdx = children.indexOf(refChild);\n if (refIdx === -1) {\n // If ref not found, append\n this.appendChild(newChild);\n return;\n }\n\n // Remove from current parent if any\n if (newChild.parentNode) {\n newChild.parentNode.removeChild(newChild);\n }\n\n newChild.parentNode = this;\n newChild.depth = this.depth + 1;\n\n children.splice(refIdx, 0, newChild);\n\n // Rebuild sibling links for the affected range\n rebuildSiblings(children);\n\n this.firstChild = children[0];\n this.lastChild = children[children.length - 1];\n\n updateDepthRecursive(newChild, this.depth + 1);\n };\n\n node.getPath = function (separator = '/'): string {\n const parts: string[] = [];\n let current: NodeInterface | null = this;\n while (current) {\n parts.unshift(current.get('text') as string ?? String(current.getId()));\n current = current.parentNode;\n }\n return separator + parts.join(separator);\n };\n\n node.cascadeBy = function (fn: (n: NodeInterface) => boolean | void): void {\n cascadeByImpl(this, fn);\n };\n\n node.bubble = function (fn: (n: NodeInterface) => boolean | void): void {\n let current: NodeInterface | null = this;\n while (current) {\n if (fn(current) === false) return;\n current = current.parentNode;\n }\n };\n\n node.contains = function (descendant: NodeInterface): boolean {\n let current: NodeInterface | null = descendant.parentNode;\n while (current) {\n if (current === (this as any)) return true;\n current = current.parentNode;\n }\n return false;\n };\n\n node.findChild = function (\n field: string,\n value: unknown,\n deep = false,\n ): NodeInterface | undefined {\n for (const child of this.childNodes) {\n if (child.get(field) === value) return child;\n if (deep) {\n const found = child.findChild(field, value, true);\n if (found) return found;\n }\n }\n return undefined;\n };\n\n node.sort = function (sorters: Sorter[]): void {\n this.childNodes.sort((a: NodeInterface, b: NodeInterface) => {\n for (const s of sorters) {\n const va = a.get(s.property) as string | number;\n const vb = b.get(s.property) as string | number;\n const dir = s.direction === 'DESC' ? -1 : 1;\n if (va < vb) return -1 * dir;\n if (va > vb) return 1 * dir;\n }\n return 0;\n });\n rebuildSiblings(this.childNodes);\n this.firstChild = this.childNodes[0] ?? null;\n this.lastChild = this.childNodes[this.childNodes.length - 1] ?? null;\n };\n\n node.serialize = function (): any {\n const data = this.getData();\n if (this.childNodes.length > 0) {\n data.children = this.childNodes.map((c: NodeInterface) => c.serialize());\n }\n return data;\n };\n\n node.eachChild = function (\n fn: (child: NodeInterface, index: number) => boolean | void,\n ): void {\n for (let i = 0; i < this.childNodes.length; i++) {\n if (fn(this.childNodes[i], i) === false) return;\n }\n };\n\n node.indexOf = function (child: NodeInterface): number {\n return this.childNodes.indexOf(child);\n };\n\n node.getChildAt = function (index: number): NodeInterface | undefined {\n return this.childNodes[index];\n };\n\n node.childCount = function (): number {\n return this.childNodes.length;\n };\n\n node.hasChildNodes = function (): boolean {\n return this.childNodes.length > 0;\n };\n\n node.getChildren = function (deep = false): NodeInterface[] {\n if (!deep) {\n return [...this.childNodes];\n }\n const result: NodeInterface[] = [];\n const collect = (n: NodeInterface): void => {\n for (const child of n.childNodes) {\n result.push(child);\n collect(child);\n }\n };\n collect(this);\n return result;\n };\n\n node.findChildBy = function (\n predicate: (n: NodeInterface) => boolean | void,\n deep = false,\n ): NodeInterface | undefined {\n for (const child of this.childNodes) {\n const matched = predicate(child);\n if (matched !== false && matched !== undefined && matched !== null) return child;\n if (deep) {\n const found = child.findChildBy(predicate, true);\n if (found) return found;\n }\n }\n return undefined;\n };\n\n node.removeAll = function (): NodeInterface[] {\n const removed = [...this.childNodes];\n for (const child of removed) {\n child.parentNode = null;\n child.previousSibling = null;\n child.nextSibling = null;\n }\n this.childNodes = [];\n this.firstChild = null;\n this.lastChild = null;\n return removed;\n };\n\n node.copy = function (deep = true): NodeInterface {\n const copyCounter = { i: 0 };\n return copyNodeImpl(this, deep, copyCounter);\n };\n\n node.getDepth = function (): number {\n return this.depth;\n };\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction rebuildSiblings(children: NodeInterface[]): void {\n for (let i = 0; i < children.length; i++) {\n children[i].previousSibling = i > 0 ? children[i - 1] : null;\n children[i].nextSibling = i < children.length - 1 ? children[i + 1] : null;\n }\n}\n\nfunction updateDepthRecursive(node: NodeInterface, depth: number): void {\n node.depth = depth;\n for (const child of node.childNodes) {\n updateDepthRecursive(child, depth + 1);\n }\n}\n\n/**\n * Recursively copies a node (and optionally its children) with new IDs.\n */\nfunction copyNodeImpl(\n node: NodeInterface,\n deep: boolean,\n counter: { i: number },\n): NodeInterface {\n counter.i += 1;\n const newId = 'copy-' + Date.now() + '-' + counter.i;\n const data = (node as any).getData() as Record<string, unknown>;\n const Ctor = (node as any).constructor as { create(data: Record<string, unknown>): any };\n const copyModel = Ctor.create({ ...data, id: newId });\n applyNodeInterface(copyModel, 0);\n const copyNode = copyModel as any as NodeInterface;\n\n if (deep) {\n for (const child of node.childNodes) {\n const childCopy = copyNodeImpl(child, true, counter);\n copyNode.appendChild(childCopy);\n }\n }\n\n return copyNode;\n}\n\n/**\n * Depth-first cascade that returns false if iteration was stopped.\n */\nfunction cascadeByImpl(\n node: NodeInterface,\n fn: (n: NodeInterface) => boolean | void,\n): boolean {\n if (fn(node) === false) return false;\n for (const child of [...node.childNodes]) {\n if (!cascadeByImpl(child, fn)) return false;\n }\n return true;\n}\n","/**\n * @framesquared/data – TreeModel\n *\n * A convenience Model subclass with NodeInterface pre-applied via create().\n */\n\nimport { Model } from '../Model.js';\nimport { applyNodeInterface } from '../mixin/NodeInterface.js';\nimport type { NodeInterface } from '../mixin/NodeInterface.js';\nimport { FieldType } from '../field/Field.js';\n\nexport class TreeModel extends Model {\n static override $className = 'Ext.data.TreeModel';\n static override idProperty = 'id';\n static defaultRootId = 'root';\n static defaultRootText = 'Root';\n\n static override fields = [\n { name: 'id', type: FieldType.AUTO },\n { name: 'text', type: FieldType.STRING, defaultValue: '' },\n { name: 'leaf', type: FieldType.BOOLEAN, defaultValue: false },\n { name: 'cls', type: FieldType.STRING, defaultValue: '' },\n { name: 'iconCls', type: FieldType.STRING, defaultValue: '' },\n { name: 'icon', type: FieldType.STRING, defaultValue: '' },\n { name: 'href', type: FieldType.STRING, defaultValue: '' },\n { name: 'hrefTarget', type: FieldType.STRING, defaultValue: '' },\n { name: 'qtip', type: FieldType.STRING, defaultValue: '' },\n { name: 'qtitle', type: FieldType.STRING, defaultValue: '' },\n { name: 'allowDrop', type: FieldType.BOOLEAN, defaultValue: true },\n { name: 'allowDrag', type: FieldType.BOOLEAN, defaultValue: true },\n ];\n\n /**\n * Factory method that creates a TreeModel instance with NodeInterface\n * already applied.\n */\n static override create(\n this: typeof Model,\n data?: Record<string, unknown>,\n ): InstanceType<typeof Model> & NodeInterface {\n const instance = super.create(data);\n applyNodeInterface(instance, 0);\n return instance as InstanceType<typeof Model> & NodeInterface;\n }\n}\n","/**\n * @framesquared/data – TreeReader\n *\n * Reads nested (hierarchical) JSON data, flattening it into a ResultSet\n * while preserving the children references.\n */\n\nimport { JsonReader } from './Reader.js';\nimport type { JsonReaderConfig } from './Reader.js';\nimport { ResultSet } from '../ResultSet.js';\n\nexport interface TreeReaderConfig extends JsonReaderConfig {\n /** Name of the property that holds child records. Defaults to 'children'. */\n childrenProperty?: string;\n}\n\nexport class TreeReader extends JsonReader {\n readonly childrenProperty: string;\n\n constructor(config: TreeReaderConfig) {\n super(config);\n this.childrenProperty = config.childrenProperty ?? 'children';\n }\n\n /**\n * Reads data, recursively collecting ALL nodes (at all levels) into a flat\n * ResultSet. The original children references are preserved on the raw\n * objects, so the tree structure is available to callers (e.g. TreeStore).\n */\n override read(data: unknown): ResultSet {\n const flat: Record<string, unknown>[] = [];\n const rootRecords = this.extractRootArray(data);\n this.collectFlat(rootRecords, flat);\n // Build ResultSet directly to avoid rootProperty re-extraction in super.read()\n const model = this.config.model;\n const records = flat.map((raw) => model.create(raw));\n return new ResultSet({ records, total: records.length, success: true });\n }\n\n /**\n * Returns `{ root, records }` where `root` is the first raw record and\n * `records` is the full flat list of all nodes.\n */\n readTree(data: Record<string, unknown>): {\n root: Record<string, unknown>;\n records: Record<string, unknown>[];\n } {\n const flat: Record<string, unknown>[] = [];\n this.collectFlat([data], flat);\n return { root: data, records: flat };\n }\n\n // ---------------------------------------------------------------------------\n // Internal helpers\n // ---------------------------------------------------------------------------\n\n private extractRootArray(data: unknown): Record<string, unknown>[] {\n if (this.config.rootProperty) {\n const root = getNestedValue(data, this.config.rootProperty);\n return Array.isArray(root) ? (root as Record<string, unknown>[]) : [];\n }\n return Array.isArray(data) ? (data as Record<string, unknown>[]) : [];\n }\n\n private collectFlat(\n items: Record<string, unknown>[],\n out: Record<string, unknown>[],\n ): void {\n for (const item of items) {\n out.push(item);\n const children = item[this.childrenProperty];\n if (Array.isArray(children) && children.length > 0) {\n this.collectFlat(children as Record<string, unknown>[], out);\n }\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Internal helper (mirrors Reader.ts private helper)\n// ---------------------------------------------------------------------------\n\nfunction getNestedValue(obj: unknown, path: string): unknown {\n const segments = path.split('.');\n let current: unknown = obj;\n for (const seg of segments) {\n if (current == null || typeof current !== 'object') return undefined;\n current = (current as Record<string, unknown>)[seg];\n }\n return current;\n}\n","/**\n * @framesquared/data – TreeWriter\n *\n * Serializes tree nodes (NodeInterface) into nested JSON structures.\n */\n\nimport type { NodeInterface } from '../mixin/NodeInterface.js';\n\nexport interface TreeWriterConfig {\n /** Name of the property used for child records. Defaults to 'children'. */\n childrenProperty?: string;\n}\n\nexport class TreeWriter {\n readonly childrenProperty: string;\n\n constructor(config?: TreeWriterConfig) {\n this.childrenProperty = config?.childrenProperty ?? 'children';\n }\n\n /**\n * Serializes an array of root-level NodeInterface records to plain objects.\n * Children are nested under the configured `childrenProperty`.\n */\n writeRecords(records: NodeInterface[]): Record<string, unknown>[] {\n return records.map((r) => this.writeRecord(r));\n }\n\n private writeRecord(record: NodeInterface): Record<string, unknown> {\n // getData() returns only the declared model fields (persistent field data)\n const data = record.getData() as Record<string, unknown>;\n\n if (record.childNodes && record.childNodes.length > 0) {\n data[this.childrenProperty] = record.childNodes.map((c: NodeInterface) =>\n this.writeRecord(c),\n );\n }\n\n return data;\n }\n}\n","/**\n * @framesquared/data – BufferedStore\n *\n * For large datasets — loads pages of data on demand via a proxy.\n * Uses a sparse page map instead of loading all records.\n * Prefetches adjacent pages based on configurable buffer zones.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { Base, Observable } from '@framesquared/core';\nimport type { Model } from '../Model.js';\nimport { Operation } from '../Operation.js';\n\n// ---------------------------------------------------------------------------\n// Observable bootstrap\n// ---------------------------------------------------------------------------\n\nconst ObservableMixin: typeof Base = Observable;\n\nfunction ensureObservable(instance: any): void {\n const proto = ObservableMixin.prototype;\n for (const name of Object.getOwnPropertyNames(proto)) {\n if (name === 'constructor') continue;\n if (name in instance) continue;\n const desc = Object.getOwnPropertyDescriptor(proto, name);\n if (desc && typeof desc.value === 'function') {\n instance[name] = desc.value.bind(instance);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Config\n// ---------------------------------------------------------------------------\n\nexport interface BufferedStoreConfig {\n model: typeof Model;\n pageSize?: number;\n leadingBufferZone?: number;\n trailingBufferZone?: number;\n proxy?: any;\n}\n\n// ---------------------------------------------------------------------------\n// BufferedStore\n// ---------------------------------------------------------------------------\n\nexport class BufferedStore extends Base {\n static override $className = 'Ext.data.BufferedStore';\n\n private pageSize: number;\n private leadingBufferZone: number;\n private trailingBufferZone: number;\n private proxyRef: any;\n\n /** Page number → array of Model records for that page. */\n private pageMap = new Map<number, Model[]>();\n\n /** Total count from the server. */\n private totalCount = 0;\n\n /** All loaded records in a flat sparse index. */\n private recordMap = new Map<number, Model>();\n\n /** Pages currently being fetched (to avoid duplicate requests). */\n private pendingPages = new Set<number>();\n\n $destroyHooks: (() => void)[] = [];\n\n constructor(config: BufferedStoreConfig) {\n super();\n ensureObservable(this);\n\n this.pageSize = config.pageSize ?? 25;\n this.leadingBufferZone = config.leadingBufferZone ?? 0;\n this.trailingBufferZone = config.trailingBufferZone ?? 0;\n this.proxyRef = config.proxy ?? null;\n }\n\n // -----------------------------------------------------------------------\n // Public API\n // -----------------------------------------------------------------------\n\n getPageSize(): number {\n return this.pageSize;\n }\n\n getCount(): number {\n return this.recordMap.size;\n }\n\n getTotalCount(): number {\n return this.totalCount;\n }\n\n getAt(index: number): Model | undefined {\n return this.recordMap.get(index);\n }\n\n isPageLoaded(pageNumber: number): boolean {\n return this.pageMap.has(pageNumber);\n }\n\n /**\n * Ensures the given range [start, end] of row indices is loaded.\n * Loads missing pages from the proxy and fires 'guaranteedrange'\n * when the requested range is fully available.\n */\n async guaranteeRange(start: number, end: number): Promise<void> {\n const startPage = Math.floor(start / this.pageSize);\n const endPage = Math.floor(end / this.pageSize);\n\n // Collect pages that need loading\n const pagesToLoad: number[] = [];\n for (let p = startPage; p <= endPage; p++) {\n if (!this.pageMap.has(p) && !this.pendingPages.has(p)) {\n pagesToLoad.push(p);\n }\n }\n\n // Load missing pages\n if (pagesToLoad.length > 0) {\n await Promise.all(pagesToLoad.map((p) => this.loadPage(p)));\n }\n\n // Fire event with the records in the requested range\n const records: Model[] = [];\n for (let i = start; i <= end; i++) {\n const rec = this.recordMap.get(i);\n if (rec) records.push(rec);\n }\n this.fire('guaranteedrange', this, records, start, end);\n\n // Prefetch buffer zones (don't await — fire and forget)\n this.prefetchBufferZones(startPage, endPage);\n }\n\n // -----------------------------------------------------------------------\n // Page loading\n // -----------------------------------------------------------------------\n\n private async loadPage(pageNumber: number): Promise<void> {\n if (!this.proxyRef) return;\n if (this.pageMap.has(pageNumber)) return;\n\n this.pendingPages.add(pageNumber);\n\n try {\n const start = pageNumber * this.pageSize;\n const op = new Operation({\n action: 'read',\n start,\n limit: this.pageSize,\n page: pageNumber + 1, // 1-based page for server\n });\n\n const rs = await this.proxyRef.read(op);\n\n if (rs.success) {\n this.pageMap.set(pageNumber, rs.records);\n\n // Index records by their absolute position\n for (let i = 0; i < rs.records.length; i++) {\n this.recordMap.set(start + i, rs.records[i]);\n }\n\n // Update total count from server\n if (rs.total > 0) {\n this.totalCount = rs.total;\n }\n }\n } finally {\n this.pendingPages.delete(pageNumber);\n }\n }\n\n // -----------------------------------------------------------------------\n // Prefetching\n // -----------------------------------------------------------------------\n\n private prefetchBufferZones(startPage: number, endPage: number): void {\n if (this.leadingBufferZone <= 0 && this.trailingBufferZone <= 0) return;\n\n const leadingPages = Math.ceil(this.leadingBufferZone / this.pageSize);\n const trailingPages = Math.ceil(this.trailingBufferZone / this.pageSize);\n\n // Prefetch leading pages (before the requested range)\n for (let p = startPage - leadingPages; p < startPage; p++) {\n if (p >= 0 && !this.pageMap.has(p) && !this.pendingPages.has(p)) {\n this.loadPage(p); // fire and forget\n }\n }\n\n // Prefetch trailing pages (after the requested range)\n const maxPage = this.totalCount > 0\n ? Math.floor((this.totalCount - 1) / this.pageSize)\n : endPage + trailingPages;\n\n for (let p = endPage + 1; p <= endPage + trailingPages && p <= maxPage; p++) {\n if (!this.pageMap.has(p) && !this.pendingPages.has(p)) {\n this.loadPage(p); // fire and forget\n }\n }\n }\n\n // -----------------------------------------------------------------------\n // Event helper\n // -----------------------------------------------------------------------\n\n private fire(eventName: string, ...args: unknown[]): void {\n if (typeof (this as any).fireEvent === 'function') {\n (this as any).fireEvent(eventName, ...args);\n }\n }\n}\n","/**\n * @framesquared/data – GraphQLProxy\n *\n * Sends GraphQL queries for read and mutations for CUD operations.\n * Parses response using a rootProperty path into the GraphQL data.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { Operation } from '../Operation.js';\nimport { ResultSet } from '../ResultSet.js';\nimport { Proxy } from './Proxy.js';\nimport type { ProxyConfig } from './Proxy.js';\n\nexport interface GraphQLProxyConfig extends ProxyConfig {\n url: string;\n query?: string;\n mutation?: string;\n rootProperty?: string;\n headers?: Record<string, string>;\n}\n\nexport class GraphQLProxy extends Proxy {\n private url: string;\n private query: string;\n private mutation: string;\n private rootProperty: string;\n private headers: Record<string, string>;\n\n constructor(config: GraphQLProxyConfig) {\n super(config);\n this.url = config.url;\n this.query = config.query ?? '';\n this.mutation = config.mutation ?? '';\n this.rootProperty = config.rootProperty ?? 'data';\n this.headers = config.headers ?? {};\n }\n\n async read(operation: Operation): Promise<ResultSet> {\n return this.doRequest(this.query, operation.params);\n }\n\n async create(operation: Operation): Promise<ResultSet> {\n const variables: Record<string, unknown> = { ...operation.params };\n if (operation.records.length > 0) {\n variables.input = operation.records[0].getData();\n }\n return this.doRequest(this.mutation, variables);\n }\n\n async update(operation: Operation): Promise<ResultSet> {\n const variables: Record<string, unknown> = { ...operation.params };\n if (operation.records.length > 0) {\n variables.input = operation.records[0].getData();\n }\n return this.doRequest(this.mutation, variables);\n }\n\n async destroy(operation: Operation): Promise<ResultSet> {\n const variables: Record<string, unknown> = { ...operation.params };\n if (operation.records.length > 0) {\n variables.id = operation.records[0].getId();\n }\n return this.doRequest(this.mutation, variables);\n }\n\n private async doRequest(\n queryStr: string,\n variables: Record<string, unknown>,\n ): Promise<ResultSet> {\n try {\n const response = await fetch(this.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...this.headers },\n body: JSON.stringify({ query: queryStr, variables }),\n });\n\n const data = await response.json();\n\n // Check for GraphQL errors\n if (data.errors && data.errors.length > 0) {\n return new ResultSet({\n records: [],\n success: false,\n message: data.errors[0].message,\n });\n }\n\n // Extract records from rootProperty path\n const raw = this.extractByPath(data, this.rootProperty);\n const items = Array.isArray(raw) ? raw : raw ? [raw] : [];\n const records = items.map((item: any) => this.model.create(item));\n\n return new ResultSet({ records, success: true });\n } catch (err: any) {\n return new ResultSet({\n records: [],\n success: false,\n message: err?.message ?? 'GraphQL request failed',\n });\n }\n }\n\n private extractByPath(obj: any, path: string): unknown {\n const parts = path.split('.');\n let current = obj;\n for (const part of parts) {\n if (current == null) return undefined;\n current = current[part];\n }\n return current;\n }\n}\n","/**\n * @framesquared/data – WebSocketProxy\n *\n * Maintains a WebSocket connection for real-time data. Sends\n * CRUD operations as JSON messages. Auto-reconnects on disconnect.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { Operation } from '../Operation.js';\nimport { ResultSet } from '../ResultSet.js';\nimport { Proxy } from './Proxy.js';\nimport type { ProxyConfig } from './Proxy.js';\n\nexport interface WebSocketProxyConfig extends ProxyConfig {\n url: string;\n protocol?: string;\n reconnect?: boolean;\n reconnectInterval?: number;\n}\n\nexport class WebSocketProxy extends Proxy {\n private url: string;\n private reconnect: boolean;\n private reconnectInterval: number;\n private ws: WebSocket | null = null;\n private listeners: Record<string, Function[]> = {};\n private intentionalClose = false;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(config: WebSocketProxyConfig) {\n super(config);\n this.url = config.url;\n this.reconnect = config.reconnect ?? false;\n this.reconnectInterval = config.reconnectInterval ?? 3000;\n }\n\n // -----------------------------------------------------------------------\n // Connection management\n // -----------------------------------------------------------------------\n\n connect(): void {\n this.intentionalClose = false;\n this.ws = new WebSocket(this.url);\n\n this.ws.onopen = () => this.fire('open');\n this.ws.onerror = (e) => this.fire('error', e);\n this.ws.onmessage = (e) => {\n try {\n const data = JSON.parse(e.data);\n this.fire('message', data);\n } catch {\n this.fire('message', e.data);\n }\n };\n this.ws.onclose = () => {\n this.fire('close');\n if (this.reconnect && !this.intentionalClose) {\n this.reconnectTimer = setTimeout(() => this.connect(), this.reconnectInterval);\n }\n };\n }\n\n disconnect(): void {\n this.intentionalClose = true;\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n this.ws?.close();\n this.ws = null;\n }\n\n // -----------------------------------------------------------------------\n // Send operations\n // -----------------------------------------------------------------------\n\n send(operation: Operation): void {\n if (!this.ws || this.ws.readyState !== 1) return;\n const message = {\n action: operation.action,\n records: operation.records.map(r => r.getData()),\n params: operation.params,\n };\n this.ws.send(JSON.stringify(message));\n }\n\n // -----------------------------------------------------------------------\n // Proxy interface (returns empty ResultSets — real data comes via events)\n // -----------------------------------------------------------------------\n\n async read(operation: Operation): Promise<ResultSet> {\n this.send(operation);\n return new ResultSet({ records: [], success: true });\n }\n\n async create(operation: Operation): Promise<ResultSet> {\n this.send(operation);\n return new ResultSet({ records: operation.records, success: true });\n }\n\n async update(operation: Operation): Promise<ResultSet> {\n this.send(operation);\n return new ResultSet({ records: operation.records, success: true });\n }\n\n async destroy(operation: Operation): Promise<ResultSet> {\n this.send(operation);\n return new ResultSet({ records: [], success: true });\n }\n\n // -----------------------------------------------------------------------\n // Events\n // -----------------------------------------------------------------------\n\n on(event: string, fn: Function): void {\n (this.listeners[event] ??= []).push(fn);\n }\n\n off(event: string, fn: Function): void {\n const list = this.listeners[event];\n if (!list) return;\n const idx = list.indexOf(fn);\n if (idx >= 0) list.splice(idx, 1);\n }\n\n private fire(event: string, ...args: unknown[]): void {\n (this.listeners[event] ?? []).forEach(fn => fn(...args));\n }\n}\n","/**\n * @framesquared/data – BatchProxy\n *\n * Combines multiple operations into a single HTTP request.\n * Unwraps the batch response into individual ResultSets.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { Operation } from '../Operation.js';\nimport { ResultSet } from '../ResultSet.js';\nimport { Proxy } from './Proxy.js';\nimport type { ProxyConfig } from './Proxy.js';\n\nexport interface BatchProxyConfig extends ProxyConfig {\n url: string;\n headers?: Record<string, string>;\n}\n\nexport class BatchProxy extends Proxy {\n private url: string;\n private headers: Record<string, string>;\n\n constructor(config: BatchProxyConfig) {\n super(config);\n this.url = config.url;\n this.headers = config.headers ?? {};\n }\n\n /**\n * Send multiple operations as a single batched request.\n * Returns an array of ResultSets, one per operation.\n */\n async sendBatch(operations: Operation[]): Promise<ResultSet[]> {\n const body = {\n operations: operations.map(op => ({\n action: op.action,\n records: op.records.map(r => r.getData()),\n params: op.params,\n })),\n };\n\n try {\n const response = await fetch(this.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...this.headers },\n body: JSON.stringify(body),\n });\n\n const data = await response.json();\n const results: ResultSet[] = [];\n\n if (data.results && Array.isArray(data.results)) {\n for (const r of data.results) {\n const records = (r.records ?? []).map((item: any) => this.model.create(item));\n results.push(new ResultSet({\n records,\n success: r.success ?? false,\n message: r.message,\n }));\n }\n }\n\n return results;\n } catch (err: any) {\n return operations.map(() => new ResultSet({\n records: [],\n success: false,\n message: err?.message ?? 'Batch request failed',\n }));\n }\n }\n\n // Proxy interface — delegate to sendBatch with single operation\n async read(operation: Operation): Promise<ResultSet> {\n const results = await this.sendBatch([operation]);\n return results[0] ?? new ResultSet({ records: [], success: false });\n }\n\n async create(operation: Operation): Promise<ResultSet> {\n const results = await this.sendBatch([operation]);\n return results[0] ?? new ResultSet({ records: [], success: false });\n }\n\n async update(operation: Operation): Promise<ResultSet> {\n const results = await this.sendBatch([operation]);\n return results[0] ?? new ResultSet({ records: [], success: false });\n }\n\n async destroy(operation: Operation): Promise<ResultSet> {\n const results = await this.sendBatch([operation]);\n return results[0] ?? new ResultSet({ records: [], success: false });\n }\n}\n","/**\n * @framesquared/data – Connection\n *\n * Centralized fetch() wrapper. Supports request and response\n * interceptors, default headers, and global error handling.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\ntype RequestInterceptor = (url: string, init: RequestInit) => [string, RequestInit];\ntype ResponseInterceptor = (response: any) => any;\ntype ErrorHandler = (error: Error) => void;\n\nconst requestInterceptors: RequestInterceptor[] = [];\nconst responseInterceptors: ResponseInterceptor[] = [];\nlet defaultHeaders: Record<string, string> = {};\nlet errorHandler: ErrorHandler | null = null;\n\nexport const Connection = {\n /**\n * Fetch with interceptors and default headers applied.\n */\n async fetch(url: string, init: RequestInit = {}): Promise<any> {\n // Apply default headers\n init.headers = { ...defaultHeaders, ...(init.headers as Record<string, string> ?? {}) };\n\n // Apply request interceptors\n let currentUrl = url;\n let currentInit = init;\n for (const interceptor of requestInterceptors) {\n [currentUrl, currentInit] = interceptor(currentUrl, currentInit);\n }\n\n try {\n let response = await fetch(currentUrl, currentInit);\n\n // Apply response interceptors\n for (const interceptor of responseInterceptors) {\n response = interceptor(response);\n }\n\n return response;\n } catch (err: any) {\n if (errorHandler) errorHandler(err);\n throw err;\n }\n },\n\n addRequestInterceptor(fn: RequestInterceptor): void {\n requestInterceptors.push(fn);\n },\n\n addResponseInterceptor(fn: ResponseInterceptor): void {\n responseInterceptors.push(fn);\n },\n\n setDefaultHeaders(headers: Record<string, string>): void {\n defaultHeaders = { ...headers };\n },\n\n setErrorHandler(handler: ErrorHandler): void {\n errorHandler = handler;\n },\n\n reset(): void {\n requestInterceptors.length = 0;\n responseInterceptors.length = 0;\n defaultHeaders = {};\n errorHandler = null;\n },\n};\n","/**\n * @framesquared/data – Session\n *\n * Manages a set of related model instances. Tracks all CRUD\n * operations as a unit. save() sends all changes via a BatchProxy.\n * commit()/reject() clear tracked changes.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { Model } from '../Model.js';\nimport { Operation } from '../Operation.js';\nimport type { BatchProxy } from '../proxy/BatchProxy.js';\nimport type { ResultSet } from '../ResultSet.js';\n\nexport interface SessionChanges {\n create: Model[];\n update: Model[];\n destroy: Model[];\n}\n\nexport class Session {\n private created = new Map<unknown, Model>();\n private updated = new Map<unknown, Model>();\n private destroyed = new Map<unknown, Model>();\n\n // -----------------------------------------------------------------------\n // Track operations\n // -----------------------------------------------------------------------\n\n trackCreate(record: Model): void {\n const key = this.recordKey(record);\n this.created.set(key, record);\n }\n\n trackUpdate(record: Model): void {\n const key = this.recordKey(record);\n // If already in created, keep it there (it's still a create)\n if (this.created.has(key)) return;\n this.updated.set(key, record);\n }\n\n trackDestroy(record: Model): void {\n const key = this.recordKey(record);\n // If it was newly created, just remove from created\n if (this.created.has(key)) {\n this.created.delete(key);\n return;\n }\n // Remove from updated if present\n this.updated.delete(key);\n this.destroyed.set(key, record);\n }\n\n // -----------------------------------------------------------------------\n // Accessors\n // -----------------------------------------------------------------------\n\n getCreated(): Model[] { return [...this.created.values()]; }\n getUpdated(): Model[] { return [...this.updated.values()]; }\n getDestroyed(): Model[] { return [...this.destroyed.values()]; }\n\n getChanges(): SessionChanges {\n return {\n create: this.getCreated(),\n update: this.getUpdated(),\n destroy: this.getDestroyed(),\n };\n }\n\n isDirty(): boolean {\n return this.created.size > 0 || this.updated.size > 0 || this.destroyed.size > 0;\n }\n\n // -----------------------------------------------------------------------\n // Save via BatchProxy\n // -----------------------------------------------------------------------\n\n async save(proxy: BatchProxy): Promise<{ success: boolean; results: ResultSet[] }> {\n const ops: Operation[] = [];\n const creates = this.getCreated();\n const updates = this.getUpdated();\n const destroys = this.getDestroyed();\n\n if (creates.length > 0) {\n ops.push(new Operation({ action: 'create', records: creates }));\n }\n if (updates.length > 0) {\n ops.push(new Operation({ action: 'update', records: updates }));\n }\n if (destroys.length > 0) {\n ops.push(new Operation({ action: 'destroy', records: destroys }));\n }\n\n if (ops.length === 0) {\n return { success: true, results: [] };\n }\n\n const results = await proxy.sendBatch(ops);\n const success = results.every(r => r.success);\n return { success, results };\n }\n\n // -----------------------------------------------------------------------\n // Commit / Reject\n // -----------------------------------------------------------------------\n\n commit(): void {\n this.created.clear();\n this.updated.clear();\n this.destroyed.clear();\n }\n\n reject(): void {\n this.created.clear();\n this.updated.clear();\n this.destroyed.clear();\n }\n\n // -----------------------------------------------------------------------\n // Helpers\n // -----------------------------------------------------------------------\n\n private recordKey(record: Model): unknown {\n // Use record identity (reference) as Map key for dedup\n return record;\n }\n}\n"],"mappings":"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","names":["FieldType","oldValue","Base","Observable","ObservableMixin","Observable","ensureObservable","Base","getNestedValue","Proxy","Proxy","Proxy","Base","Observable","ObservableMixin","Observable","ensureObservable","Base","getNestedValue","Base","Observable","ObservableMixin","Observable","ensureObservable","Base","Proxy","Proxy","Proxy"]}
1
+ {"version":3,"sources":["../src/Model.ts","../src/field/Field.ts","../src/association/Association.ts","../src/association/HasOne.ts","../src/association/HasMany.ts","../src/association/BelongsTo.ts","../src/association/ManyToMany.ts","../src/Schema.ts","../src/ModelCollection.ts","../src/validators.ts","../src/store/Store.ts","../src/store/Collection.ts","../src/ResultSet.ts","../src/reader/Reader.ts","../src/writer/Writer.ts","../src/proxy/Proxy.ts","../src/proxy/ClientProxy.ts","../src/proxy/ServerProxy.ts","../src/store/TreeStore.ts","../src/mixin/NodeInterface.ts","../src/model/TreeModel.ts","../src/reader/TreeReader.ts","../src/writer/TreeWriter.ts","../src/store/BufferedStore.ts","../src/proxy/GraphQLProxy.ts","../src/proxy/WebSocketProxy.ts","../src/proxy/BatchProxy.ts","../src/data/Connection.ts","../src/data/Session.ts"],"sourcesContent":["/**\n * @framesquared/data – Model\n *\n * The foundation of the data layer. A Model represents a record with\n * typed fields, dirty tracking, validation, and event notification.\n *\n * Instances are wrapped in a Proxy so `record.name` transparently\n * delegates to `get('name')` / `set('name', value)` for field access.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { Base, Observable } from '@framesquared/core';\nimport { type Field, createField } from './field/Field.js';\nimport type { FieldDefinition } from './field/Field.js';\nimport { Schema } from './Schema.js';\nimport type { Association } from './association/Association.js';\nimport { ModelCollection, ManyToManyCollection } from './ModelCollection.js';\n\n// ---------------------------------------------------------------------------\n// ValidationResult\n// ---------------------------------------------------------------------------\n\nexport interface ValidationError {\n field: string;\n message: string;\n}\n\nexport interface ValidationResult {\n valid: boolean;\n errors: ValidationError[];\n}\n\n// ---------------------------------------------------------------------------\n// Field resolution helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Resolves a dot-separated mapping path from raw data.\n */\nfunction getNestedValue(data: Record<string, unknown>, path: string): unknown {\n const segments = path.split('.');\n let current: unknown = data;\n for (const seg of segments) {\n if (current === null || current === undefined || typeof current !== 'object') {\n return undefined;\n }\n current = (current as Record<string, unknown>)[seg];\n }\n return current;\n}\n\n// ---------------------------------------------------------------------------\n// Proxy handler\n// ---------------------------------------------------------------------------\n\nconst MODEL_PROPS = new Set<string | symbol>([\n // Commonly accessed non-field properties/methods that should NOT\n // be intercepted by the proxy's field get/set logic.\n 'constructor',\n 'prototype',\n '__proto__',\n 'get',\n 'set',\n 'getData',\n 'getId',\n 'setId',\n 'isModified',\n 'getChanges',\n 'commit',\n 'reject',\n 'validate',\n 'isValid',\n 'on',\n 'un',\n 'fireEvent',\n 'fireEventArgs',\n 'addListener',\n 'removeListener',\n 'hasListener',\n 'clearListeners',\n 'suspendEvents',\n 'resumeEvents',\n 'isSuspended',\n 'mon',\n 'mun',\n 'relayEvents',\n 'fireEventedAction',\n 'destroy',\n 'isDestroyed',\n '$destroyHooks',\n '$className',\n 'self',\n '$callStack',\n '$configInitialized',\n '$pendingConfig',\n 'hasMixin',\n 'initConfig',\n 'callParent',\n 'modified',\n 'phantom',\n '$associations',\n '$fieldMap',\n '$data',\n Symbol.dispose,\n Symbol.toPrimitive,\n Symbol.toStringTag,\n]);\n\nfunction createModelProxy(model: Model): Model {\n return new Proxy(model, {\n get(target, prop, receiver) {\n // If it's a known Model/Base property or symbol, use normal access\n if (MODEL_PROPS.has(prop) || typeof prop === 'symbol') {\n return Reflect.get(target, prop, receiver);\n }\n // If it exists directly on the instance or prototype, use normal access\n if (prop in target) {\n const desc =\n Object.getOwnPropertyDescriptor(target, prop) ??\n Object.getOwnPropertyDescriptor(Object.getPrototypeOf(target), prop);\n if (desc?.get || typeof desc?.value === 'function') {\n return Reflect.get(target, prop, receiver);\n }\n }\n // Check if it's a field name\n if (typeof prop === 'string' && target.$fieldMap?.has(prop)) {\n return target.get(prop);\n }\n return Reflect.get(target, prop, receiver);\n },\n set(target, prop, value, receiver) {\n if (typeof prop === 'string' && target.$fieldMap?.has(prop)) {\n target.set(prop, value);\n return true;\n }\n return Reflect.set(target, prop, value, receiver);\n },\n });\n}\n\n// ---------------------------------------------------------------------------\n// Model class\n// ---------------------------------------------------------------------------\n\n// Register the Observable mixin class (defined by core's define())\nconst ObservableMixin: typeof Base = Observable;\n\nexport class Model extends Base {\n static override $className = 'Ext.data.Model';\n\n /** Field definitions — override in subclasses. */\n static fields: (FieldDefinition | string)[] = [];\n\n /** Name of the ID field. */\n static idProperty = 'id';\n\n // -- Instance state (non-enumerable to keep proxy clean) --\n\n /** Resolved Field instances keyed by name. */\n $fieldMap!: Map<string, Field>;\n\n /** Current field values. */\n $data!: Record<string, unknown>;\n\n /** Previous values for dirty fields (fieldName → old value). */\n modified: Record<string, unknown> = {};\n\n /** Per-instance association storage: assocName → Model | ModelCollection */\n $associations = new Map<string, Model | ModelCollection | ManyToManyCollection>();\n\n // -----------------------------------------------------------------------\n // Construction\n // -----------------------------------------------------------------------\n\n constructor(_data?: Record<string, unknown>) {\n super();\n // Will be called by create() which sets up fields + proxy\n }\n\n /**\n * Factory method that sets up fields, applies data, wraps in proxy.\n */\n static override create(this: typeof Model, data?: Record<string, unknown>): Model {\n const instance = new this();\n instance.$fieldMap = new Map();\n instance.$data = {};\n instance.modified = {};\n instance.$associations = new Map();\n\n // Resolve field definitions\n const fieldDefs = (this as any).fields as (FieldDefinition | string)[];\n for (const def of fieldDefs) {\n const field = createField(def);\n instance.$fieldMap.set(field.name, field);\n }\n\n // Apply Observable mixin methods if not already present\n ensureObservable(instance);\n\n // Load initial data\n instance.$loadData(data ?? {});\n\n // Process associations — install getters/setters, load nested data\n installAssociations(instance, data ?? {});\n\n // Wrap in proxy\n return createModelProxy(instance);\n }\n\n // -----------------------------------------------------------------------\n // Data loading (initial — not dirty)\n // -----------------------------------------------------------------------\n\n /** @internal Loads initial data without marking as dirty. */\n $loadData(rawData: Record<string, unknown>): void {\n // Store non-schema fields as-is (pass-through for custom data)\n for (const [key, value] of Object.entries(rawData)) {\n if (!this.$fieldMap.has(key)) {\n this.$data[key] = value;\n }\n }\n\n for (const [name, field] of this.$fieldMap) {\n let value: unknown;\n\n // Check mapping first\n if (field.mapping) {\n value = getNestedValue(rawData, field.mapping);\n } else {\n value = rawData[name];\n }\n\n // Apply field conversion\n if (value !== undefined) {\n value = field.convert(value, this);\n } else {\n value = field.defaultValue;\n if (value !== undefined) {\n value = field.convert(value, this);\n }\n }\n\n this.$data[name] = value;\n }\n }\n\n // -----------------------------------------------------------------------\n // get / set\n // -----------------------------------------------------------------------\n\n get(fieldName: string): unknown {\n return this.$data[fieldName];\n }\n\n set(fieldNameOrData: string | Record<string, unknown>, value?: unknown): string[] {\n const changes: Record<string, unknown> =\n typeof fieldNameOrData === 'string' ? { [fieldNameOrData]: value } : fieldNameOrData;\n\n const modifiedFields: string[] = [];\n\n for (const [name, newValue] of Object.entries(changes)) {\n const field = this.$fieldMap.get(name);\n if (!field) {\n // Pass-through for non-schema fields\n const oldValue = this.$data[name];\n if (newValue !== oldValue) {\n if (!(name in this.modified)) this.modified[name] = oldValue;\n this.$data[name] = newValue;\n modifiedFields.push(name);\n }\n continue;\n }\n\n const converted = field.convert(newValue, this);\n const oldValue = this.$data[name];\n\n if (converted === oldValue) continue;\n\n // Track dirty state — only store the first original value\n if (!(name in this.modified)) {\n this.modified[name] = oldValue;\n }\n\n this.$data[name] = converted;\n modifiedFields.push(name);\n\n // Fire idchanged if the id field changed\n const Ctor = this.constructor as typeof Model;\n if (name === Ctor.idProperty && typeof (this as any).fireEvent === 'function') {\n (this as any).fireEvent('idchanged', this, converted, oldValue);\n }\n }\n\n if (modifiedFields.length > 0 && typeof (this as any).fireEvent === 'function') {\n (this as any).fireEvent('change', this, modifiedFields);\n }\n\n return modifiedFields;\n }\n\n getData(options?: { serialize?: boolean }): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [name, field] of this.$fieldMap) {\n const value = this.$data[name];\n result[name] = options?.serialize ? field.serialize(value, this) : value;\n }\n return result;\n }\n\n // -----------------------------------------------------------------------\n // Dirty tracking\n // -----------------------------------------------------------------------\n\n isModified(fieldName?: string): boolean {\n if (fieldName) {\n return fieldName in this.modified;\n }\n return Object.keys(this.modified).length > 0;\n }\n\n getChanges(): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const name of Object.keys(this.modified)) {\n result[name] = this.$data[name];\n }\n return result;\n }\n\n commit(silent?: boolean): void {\n this.modified = {};\n if (!silent && typeof (this as any).fireEvent === 'function') {\n (this as any).fireEvent('commit', this);\n }\n }\n\n reject(silent?: boolean): void {\n // Revert to previous values\n for (const [name, oldValue] of Object.entries(this.modified)) {\n this.$data[name] = oldValue;\n }\n this.modified = {};\n if (!silent && typeof (this as any).fireEvent === 'function') {\n (this as any).fireEvent('reject', this);\n }\n }\n\n // -----------------------------------------------------------------------\n // Identification\n // -----------------------------------------------------------------------\n\n getId(): string | number {\n const Ctor = this.constructor as typeof Model;\n return this.$data[Ctor.idProperty] as string | number;\n }\n\n setId(id: string | number): void {\n const Ctor = this.constructor as typeof Model;\n this.set(Ctor.idProperty, id);\n }\n\n get phantom(): boolean {\n const id = this.getId();\n return id === undefined || id === null || id === 0 || id === '';\n }\n\n // -----------------------------------------------------------------------\n // Validation\n // -----------------------------------------------------------------------\n\n validate(): ValidationResult {\n const errors: ValidationError[] = [];\n\n for (const [name, field] of this.$fieldMap) {\n const value = this.$data[name];\n for (const validator of field.validators) {\n const msg = validator(value, this);\n if (msg) {\n errors.push({ field: name, message: msg });\n }\n }\n }\n\n return { valid: errors.length === 0, errors };\n }\n\n isValid(): boolean {\n return this.validate().valid;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Observable mixin integration\n// ---------------------------------------------------------------------------\n\n/**\n * Ensures the Observable mixin methods are available on the instance.\n * We copy prototype methods from Observable to Model instances at runtime.\n */\nfunction ensureObservable(instance: Model): void {\n const proto = ObservableMixin.prototype;\n for (const name of Object.getOwnPropertyNames(proto)) {\n if (name === 'constructor') continue;\n if (name in instance) continue;\n const desc = Object.getOwnPropertyDescriptor(proto, name);\n if (desc && typeof desc.value === 'function') {\n (instance as any)[name] = desc.value.bind(instance);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Association integration\n// ---------------------------------------------------------------------------\n\n/**\n * Processes all associations for the given instance's model class.\n * Installs getters/setters, loads nested data, sets up cascade hooks.\n */\nfunction installAssociations(instance: Model, rawData: Record<string, unknown>): void {\n const modelName = (instance.constructor as typeof Model).$className;\n const assocs = Schema.getAssociations(modelName);\n if (assocs.length === 0) return;\n\n for (const assoc of assocs) {\n if (!assoc.associatedModel) continue;\n\n switch (assoc.type) {\n case 'hasOne':\n installHasOne(instance, assoc, rawData);\n break;\n case 'hasMany':\n installHasMany(instance, assoc, rawData);\n break;\n case 'belongsTo':\n installBelongsTo(instance, assoc, rawData);\n break;\n case 'manyToMany':\n installManyToMany(instance, assoc, rawData);\n break;\n }\n }\n}\n\nfunction installHasOne(\n instance: Model,\n assoc: Association,\n rawData: Record<string, unknown>,\n): void {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const AssocModel = assoc.associatedModel!;\n const name = assoc.associationName;\n const getterName = assoc.getterName;\n const setterName = assoc.setterName;\n\n // Initialise storage\n instance.$associations.set(name, null as any);\n\n // Getter\n (instance as any)[getterName] = function (): Model | null {\n return (instance.$associations.get(name) as Model) ?? null;\n };\n\n // Setter\n (instance as any)[setterName] = function (child: Model): void {\n instance.$associations.set(name, child);\n // Set foreignKey on child pointing back to this parent\n const parentId = instance.get(assoc.primaryKey);\n if (parentId !== undefined && child.$fieldMap?.has(assoc.foreignKey)) {\n child.set(assoc.foreignKey, parentId);\n }\n };\n\n // Load from nested data\n const nestedData = rawData[name];\n if (nestedData && typeof nestedData === 'object' && !Array.isArray(nestedData)) {\n const childData = { ...(nestedData as Record<string, unknown>) };\n // Set foreignKey\n const parentId = instance.get(assoc.primaryKey);\n if (parentId !== undefined) {\n childData[assoc.foreignKey] = parentId;\n }\n const child = AssocModel.create(childData);\n instance.$associations.set(name, child);\n }\n\n // Cascade destroy\n if (assoc.cascade) {\n instance.$destroyHooks.push(() => {\n const child = instance.$associations.get(name) as Model | null;\n if (child && !child.isDestroyed) child.destroy();\n });\n }\n}\n\nfunction installHasMany(\n instance: Model,\n assoc: Association,\n rawData: Record<string, unknown>,\n): void {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const AssocModel = assoc.associatedModel!;\n const name = assoc.associationName;\n const collection = new ModelCollection();\n instance.$associations.set(name, collection);\n\n // Collection accessor — wraps add() to auto-set foreignKey\n const wrappedCollection = {\n getCount: () => collection.getCount(),\n getAll: () => collection.getAll(),\n getById: (id: string | number) => collection.getById(id),\n filter: (fn: (record: Model) => boolean) => collection.filter(fn),\n add(child: Model) {\n const parentId = instance.get(assoc.primaryKey);\n if (parentId !== undefined && child.$fieldMap?.has(assoc.foreignKey)) {\n child.set(assoc.foreignKey, parentId);\n }\n collection.add(child);\n },\n remove(child: Model) {\n collection.remove(child);\n },\n };\n\n // Accessor method (e.g., user.orders())\n (instance as any)[name] = function () {\n return wrappedCollection;\n };\n\n // Load from nested data\n const nestedData = rawData[name];\n if (Array.isArray(nestedData)) {\n const parentId = instance.get(assoc.primaryKey);\n for (const itemData of nestedData) {\n if (typeof itemData === 'object' && itemData !== null) {\n const childData = { ...(itemData as Record<string, unknown>) };\n if (parentId !== undefined) {\n childData[assoc.foreignKey] = parentId;\n }\n const child = AssocModel.create(childData);\n collection.add(child);\n }\n }\n }\n\n // Cascade destroy\n if (assoc.cascade) {\n instance.$destroyHooks.push(() => {\n collection.destroyAll();\n });\n }\n}\n\nfunction installBelongsTo(\n instance: Model,\n assoc: Association,\n rawData: Record<string, unknown>,\n): void {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const AssocModel = assoc.associatedModel!;\n const name = assoc.associationName;\n const getterName = assoc.getterName;\n const setterName = assoc.setterName;\n\n // Initialise storage\n instance.$associations.set(name, null as any);\n\n // Getter\n (instance as any)[getterName] = function (): Model | null {\n return (instance.$associations.get(name) as Model) ?? null;\n };\n\n // Setter\n (instance as any)[setterName] = function (parent: Model): void {\n instance.$associations.set(name, parent);\n // Update foreignKey on self\n const parentId = parent.get(assoc.primaryKey);\n if (parentId !== undefined && instance.$fieldMap?.has(assoc.foreignKey)) {\n instance.set(assoc.foreignKey, parentId);\n }\n };\n\n // Load from nested data\n const nestedData = rawData[name];\n if (nestedData && typeof nestedData === 'object' && !Array.isArray(nestedData)) {\n const parent = AssocModel.create(nestedData as Record<string, unknown>);\n instance.$associations.set(name, parent);\n }\n}\n\nfunction installManyToMany(\n instance: Model,\n assoc: Association,\n rawData: Record<string, unknown>,\n): void {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const AssocModel = assoc.associatedModel!;\n const name = assoc.associationName;\n const collection = new ManyToManyCollection();\n instance.$associations.set(name, collection);\n\n // Accessor method\n (instance as any)[name] = function () {\n return collection;\n };\n\n // Load from nested data\n const nestedData = rawData[name];\n if (Array.isArray(nestedData)) {\n for (const itemData of nestedData) {\n if (typeof itemData === 'object' && itemData !== null) {\n const child = AssocModel.create(itemData as Record<string, unknown>);\n collection.link(child);\n }\n }\n }\n}\n","/**\n * @framesquared/data – Field system\n *\n * Defines field types with type coercion, serialization, and defaults.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\n// ---------------------------------------------------------------------------\n// FieldType enum\n// ---------------------------------------------------------------------------\n\nexport enum FieldType {\n STRING = 'string',\n INT = 'int',\n FLOAT = 'float',\n BOOLEAN = 'boolean',\n DATE = 'date',\n AUTO = 'auto',\n}\n\n// ---------------------------------------------------------------------------\n// Validator type (function signature)\n// ---------------------------------------------------------------------------\n\nexport type Validator = (value: unknown, record?: any) => string | null;\n\n// ---------------------------------------------------------------------------\n// FieldDefinition\n// ---------------------------------------------------------------------------\n\nexport interface FieldDefinition {\n name: string;\n type?: FieldType;\n defaultValue?: unknown;\n convert?: (value: unknown, record?: any) => unknown;\n serialize?: (value: unknown, record?: any) => unknown;\n mapping?: string;\n persist?: boolean;\n critical?: boolean;\n allowNull?: boolean;\n sortType?: string;\n validators?: Validator[];\n}\n\n// ---------------------------------------------------------------------------\n// Base Field class\n// ---------------------------------------------------------------------------\n\nexport abstract class Field {\n readonly name: string;\n readonly type: FieldType;\n readonly mapping: string | undefined;\n readonly persist: boolean;\n readonly critical: boolean;\n readonly allowNull: boolean;\n readonly sortType: string | undefined;\n readonly validators: Validator[];\n private readonly customConvert?: (value: unknown, record?: any) => unknown;\n private readonly customSerialize?: (value: unknown, record?: any) => unknown;\n private readonly customDefault: unknown;\n\n constructor(def: FieldDefinition) {\n this.name = def.name;\n this.type = def.type ?? FieldType.AUTO;\n this.mapping = def.mapping;\n this.persist = def.persist ?? true;\n this.critical = def.critical ?? false;\n this.allowNull = def.allowNull ?? false;\n this.sortType = def.sortType;\n this.validators = def.validators ?? [];\n this.customConvert = def.convert;\n this.customSerialize = def.serialize;\n this.customDefault = def.defaultValue;\n }\n\n /** Type-specific default (overridden by subclasses). */\n get defaultValue(): unknown {\n return this.customDefault !== undefined ? this.customDefault : this.getTypeDefault();\n }\n\n /** Subclass provides the type-specific default. */\n protected abstract getTypeDefault(): unknown;\n\n /**\n * Converts a raw value to the field's type.\n * If a custom `convert` was specified in the definition, it is used.\n * Otherwise delegates to the subclass's `coerce()`.\n */\n convert(value: unknown, record?: any): unknown {\n if (this.customConvert) {\n return this.customConvert(value, record);\n }\n if (value === null && this.allowNull) return null;\n if (value === undefined) return this.defaultValue;\n return this.coerce(value);\n }\n\n /** Type-specific coercion (subclasses override). */\n protected abstract coerce(value: unknown): unknown;\n\n /**\n * Serializes a value for transport.\n */\n serialize(value: unknown, record?: any): unknown {\n if (this.customSerialize) {\n return this.customSerialize(value, record);\n }\n return value;\n }\n}\n\n// ---------------------------------------------------------------------------\n// StringField\n// ---------------------------------------------------------------------------\n\nexport class StringField extends Field {\n constructor(def: Omit<FieldDefinition, 'type'> & { type?: FieldType }) {\n super({ ...def, type: FieldType.STRING });\n }\n\n protected getTypeDefault(): unknown {\n return '';\n }\n\n protected coerce(value: unknown): unknown {\n if (value === null) return '';\n return String(value);\n }\n}\n\n// ---------------------------------------------------------------------------\n// IntField\n// ---------------------------------------------------------------------------\n\nexport class IntField extends Field {\n constructor(def: Omit<FieldDefinition, 'type'> & { type?: FieldType }) {\n super({ ...def, type: FieldType.INT });\n }\n\n protected getTypeDefault(): unknown {\n return 0;\n }\n\n protected coerce(value: unknown): unknown {\n if (value === null) return 0;\n if (typeof value === 'boolean') return value ? 1 : 0;\n const n = parseInt(String(value), 10);\n return Number.isNaN(n) ? 0 : n;\n }\n}\n\n// ---------------------------------------------------------------------------\n// FloatField\n// ---------------------------------------------------------------------------\n\nexport class FloatField extends Field {\n constructor(def: Omit<FieldDefinition, 'type'> & { type?: FieldType }) {\n super({ ...def, type: FieldType.FLOAT });\n }\n\n protected getTypeDefault(): unknown {\n return 0;\n }\n\n protected coerce(value: unknown): unknown {\n if (value === null) return 0;\n if (typeof value === 'boolean') return value ? 1 : 0;\n const n = parseFloat(String(value));\n return Number.isNaN(n) ? 0 : n;\n }\n}\n\n// ---------------------------------------------------------------------------\n// BooleanField\n// ---------------------------------------------------------------------------\n\nconst FALSE_STRINGS = new Set(['false', '0', 'no', 'off', '']);\n\nexport class BooleanField extends Field {\n constructor(def: Omit<FieldDefinition, 'type'> & { type?: FieldType }) {\n super({ ...def, type: FieldType.BOOLEAN });\n }\n\n protected getTypeDefault(): unknown {\n return false;\n }\n\n protected coerce(value: unknown): unknown {\n if (value === null || value === undefined) return false;\n if (typeof value === 'string') {\n return !FALSE_STRINGS.has(value.toLowerCase());\n }\n return Boolean(value);\n }\n}\n\n// ---------------------------------------------------------------------------\n// DateField\n// ---------------------------------------------------------------------------\n\nexport class DateField extends Field {\n constructor(def: Omit<FieldDefinition, 'type'> & { type?: FieldType }) {\n super({ ...def, type: FieldType.DATE });\n }\n\n protected getTypeDefault(): unknown {\n return null;\n }\n\n protected coerce(value: unknown): unknown {\n if (value instanceof Date) return value;\n if (typeof value === 'number') return new Date(value);\n if (typeof value === 'string') {\n const d = new Date(value);\n return Number.isNaN(d.getTime()) ? null : d;\n }\n return null;\n }\n\n override serialize(value: unknown): unknown {\n if (value instanceof Date) return value.toISOString();\n return value;\n }\n}\n\n// ---------------------------------------------------------------------------\n// AutoField\n// ---------------------------------------------------------------------------\n\nexport class AutoField extends Field {\n constructor(def: Omit<FieldDefinition, 'type'> & { type?: FieldType }) {\n super({ ...def, type: FieldType.AUTO });\n }\n\n protected getTypeDefault(): unknown {\n return undefined;\n }\n\n protected coerce(value: unknown): unknown {\n return value;\n }\n}\n\n// ---------------------------------------------------------------------------\n// createField factory\n// ---------------------------------------------------------------------------\n\nconst FIELD_CONSTRUCTORS: Record<string, new (def: FieldDefinition) => Field> = {\n [FieldType.STRING]: StringField,\n [FieldType.INT]: IntField,\n [FieldType.FLOAT]: FloatField,\n [FieldType.BOOLEAN]: BooleanField,\n [FieldType.DATE]: DateField,\n [FieldType.AUTO]: AutoField,\n};\n\n/**\n * Creates a Field instance from a definition or shorthand string.\n */\nexport function createField(def: FieldDefinition | string): Field {\n if (typeof def === 'string') {\n return new AutoField({ name: def });\n }\n const type = def.type ?? FieldType.AUTO;\n const Ctor = FIELD_CONSTRUCTORS[type] ?? AutoField;\n return new Ctor(def);\n}\n","/**\n * @framesquared/data – Association (base class)\n */\n\nimport type { Model } from '../Model.js';\n\nexport interface AssociationConfig {\n model: string | typeof Model;\n foreignKey: string;\n primaryKey?: string;\n getterName?: string;\n setterName?: string;\n cascade?: boolean;\n /** For ManyToMany: junction model name or class */\n through?: string;\n /** For ManyToMany: the other foreign key in the junction */\n otherKey?: string;\n}\n\nexport type AssociationType = 'hasOne' | 'hasMany' | 'belongsTo' | 'manyToMany';\n\nexport class Association {\n readonly type: AssociationType;\n readonly config: AssociationConfig;\n readonly ownerModelName: string;\n\n /** Resolved associated model class (may be null until forward ref resolves). */\n associatedModel: typeof Model | null = null;\n\n constructor(type: AssociationType, ownerModelName: string, config: AssociationConfig) {\n this.type = type;\n this.ownerModelName = ownerModelName;\n this.config = config;\n }\n\n /**\n * The property name used for nested JSON loading and as the\n * default getter/collection accessor name.\n */\n get associationName(): string {\n if (!this.associatedModel) return '';\n // Derive from classname: 'test.Address' → 'address', 'test.Order' → 'orders'\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const raw = this.associatedModel.$className.split('.').pop()!;\n const lower = raw[0].toLowerCase() + raw.slice(1);\n if (this.type === 'hasMany' || this.type === 'manyToMany') {\n // Simple pluralise: add 's'\n return lower.endsWith('s') ? lower : lower + 's';\n }\n return lower;\n }\n\n get getterName(): string {\n if (this.config.getterName) return this.config.getterName;\n const name = this.associationName;\n return `get${name[0].toUpperCase()}${name.slice(1)}`;\n }\n\n get setterName(): string {\n if (this.config.setterName) return this.config.setterName;\n const name = this.associationName;\n return `set${name[0].toUpperCase()}${name.slice(1)}`;\n }\n\n get foreignKey(): string {\n return this.config.foreignKey;\n }\n\n get primaryKey(): string {\n return this.config.primaryKey ?? 'id';\n }\n\n get cascade(): boolean {\n return this.config.cascade ?? false;\n }\n}\n","/**\n * @framesquared/data – HasOne association\n */\nimport { Association } from './Association.js';\nimport type { AssociationConfig } from './Association.js';\n\nexport class HasOne extends Association {\n constructor(ownerModelName: string, config: AssociationConfig) {\n super('hasOne', ownerModelName, config);\n }\n}\n","/**\n * @framesquared/data – HasMany association\n */\nimport { Association } from './Association.js';\nimport type { AssociationConfig } from './Association.js';\n\nexport class HasMany extends Association {\n constructor(ownerModelName: string, config: AssociationConfig) {\n super('hasMany', ownerModelName, config);\n }\n}\n","/**\n * @framesquared/data – BelongsTo association\n */\nimport { Association } from './Association.js';\nimport type { AssociationConfig } from './Association.js';\n\nexport class BelongsTo extends Association {\n constructor(ownerModelName: string, config: AssociationConfig) {\n super('belongsTo', ownerModelName, config);\n }\n}\n","/**\n * @framesquared/data – ManyToMany association\n */\nimport { Association } from './Association.js';\nimport type { AssociationConfig } from './Association.js';\n\nexport class ManyToMany extends Association {\n constructor(ownerModelName: string, config: AssociationConfig) {\n super('manyToMany', ownerModelName, config);\n }\n\n get through(): string {\n return this.config.through ?? '';\n }\n\n get otherKey(): string {\n return this.config.otherKey ?? '';\n }\n}\n","/**\n * @framesquared/data – Schema\n *\n * Singleton registry for Model classes and their associations.\n * Handles forward references: if Model A declares an association to\n * Model B by string name before B is registered, the reference is\n * resolved when B is later registered.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { Model } from './Model.js';\nimport type { Association } from './association/Association.js';\nimport type { AssociationConfig } from './association/Association.js';\nimport { HasOne } from './association/HasOne.js';\nimport { HasMany } from './association/HasMany.js';\nimport { BelongsTo } from './association/BelongsTo.js';\nimport { ManyToMany } from './association/ManyToMany.js';\n\n// ---------------------------------------------------------------------------\n// Internal storage\n// ---------------------------------------------------------------------------\n\n/** className → Model class */\nconst models = new Map<string, typeof Model>();\n\n/** className → Association[] (owned by that model) */\nconst associations = new Map<string, Association[]>();\n\n/** modelName → list of unresolved Association references waiting for it */\nconst pendingReferences = new Map<string, Association[]>();\n\n// ---------------------------------------------------------------------------\n// SchemaImpl\n// ---------------------------------------------------------------------------\n\nclass SchemaImpl {\n /**\n * Registers a Model class and processes its association declarations.\n * If the model has `static hasOne`, `static hasMany`, `static belongsTo`,\n * or `static manyToMany` arrays, creates Association instances for each.\n */\n register(ModelClass: typeof Model): void {\n const name = ModelClass.$className;\n models.set(name, ModelClass);\n\n // Process association declarations\n this.processAssociations(ModelClass, 'hasOne', HasOne);\n this.processAssociations(ModelClass, 'hasMany', HasMany);\n this.processAssociations(ModelClass, 'belongsTo', BelongsTo);\n this.processAssociations(ModelClass, 'manyToMany', ManyToMany);\n\n // Resolve any pending forward references to this model\n const pending = pendingReferences.get(name);\n if (pending) {\n for (const assoc of pending) {\n assoc.associatedModel = ModelClass;\n }\n pendingReferences.delete(name);\n }\n }\n\n /**\n * Retrieves a registered Model class by name.\n */\n get(name: string): typeof Model | undefined {\n return models.get(name);\n }\n\n /**\n * Returns all Association instances owned by the given model name.\n */\n getAssociations(modelName: string): Association[] {\n return associations.get(modelName) ?? [];\n }\n\n /**\n * Clears all registrations (for testing).\n */\n clear(): void {\n models.clear();\n associations.clear();\n pendingReferences.clear();\n }\n\n // -----------------------------------------------------------------------\n // Internal: process static association arrays\n // -----------------------------------------------------------------------\n\n private processAssociations(\n ModelClass: typeof Model,\n staticProp: string,\n AssocClass: new (ownerName: string, config: AssociationConfig) => Association,\n ): void {\n const configs = (ModelClass as any)[staticProp] as AssociationConfig[] | undefined;\n if (!configs || !Array.isArray(configs)) return;\n\n const ownerName = ModelClass.$className;\n if (!associations.has(ownerName)) {\n associations.set(ownerName, []);\n }\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const list = associations.get(ownerName)!;\n\n for (const config of configs) {\n const assoc = new AssocClass(ownerName, config);\n\n // Resolve model reference\n const modelRef = config.model;\n if (typeof modelRef === 'string') {\n const resolved = models.get(modelRef);\n if (resolved) {\n assoc.associatedModel = resolved;\n } else {\n // Forward reference — park it for later resolution\n if (!pendingReferences.has(modelRef)) {\n pendingReferences.set(modelRef, []);\n }\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n pendingReferences.get(modelRef)!.push(assoc);\n }\n } else {\n // Direct class reference\n assoc.associatedModel = modelRef as typeof Model;\n }\n\n list.push(assoc);\n }\n }\n}\n\n/** Singleton. */\nexport const Schema = new SchemaImpl();\n","/**\n * @framesquared/data – ModelCollection\n *\n * A lightweight collection of Model instances, used by HasMany and\n * ManyToMany associations. Provides add/remove/filter/getById.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { Model } from './Model.js';\n\nexport class ModelCollection {\n private items: Model[] = [];\n\n getCount(): number {\n return this.items.length;\n }\n\n getAll(): Model[] {\n return [...this.items];\n }\n\n add(record: Model): void {\n if (!this.items.includes(record)) {\n this.items.push(record);\n }\n }\n\n remove(record: Model): void {\n const idx = this.items.indexOf(record);\n if (idx !== -1) this.items.splice(idx, 1);\n }\n\n getById(id: string | number): Model | undefined {\n return this.items.find((r) => r.getId() === id);\n }\n\n filter(fn: (record: Model) => boolean): Model[] {\n return this.items.filter(fn);\n }\n\n destroyAll(): void {\n for (const item of this.items) {\n if (!item.isDestroyed) item.destroy();\n }\n this.items.length = 0;\n }\n}\n\n/**\n * Extended collection for ManyToMany that exposes link/unlink semantics.\n */\nexport class ManyToManyCollection extends ModelCollection {\n private junctions = new Map<Model, any>();\n\n link(record: Model, _junctionData?: Record<string, unknown>): void {\n this.add(record);\n this.junctions.set(record, _junctionData ?? {});\n }\n\n unlink(record: Model): void {\n this.remove(record);\n this.junctions.delete(record);\n }\n}\n","/**\n * @framesquared/data – Built-in validators\n *\n * Each factory returns a Validator function: (value) => errorMsg | null\n */\n\nimport type { Validator } from './field/Field.js';\n\n/**\n * Value must not be null, undefined, or empty string.\n */\nexport function presence(message = 'is required'): Validator {\n return (value: unknown) => {\n if (value === null || value === undefined || value === '') {\n return message;\n }\n return null;\n };\n}\n\n/**\n * String length must be within min/max bounds.\n */\nexport function length(opts: { min?: number; max?: number; message?: string }): Validator {\n return (value: unknown) => {\n const str = String(value ?? '');\n if (opts.min !== undefined && str.length < opts.min) {\n return opts.message ?? `must be at least ${opts.min} characters`;\n }\n if (opts.max !== undefined && str.length > opts.max) {\n return opts.message ?? `must be at most ${opts.max} characters`;\n }\n return null;\n };\n}\n\n/**\n * Value must match the given regex.\n */\nexport function formatValidator(pattern: RegExp, message?: string): Validator {\n return (value: unknown) => {\n if (!pattern.test(String(value ?? ''))) {\n return message ?? `does not match the required format`;\n }\n return null;\n };\n}\n\n/**\n * Value must be in the allowed list.\n */\nexport function inclusion(list: unknown[], message?: string): Validator {\n return (value: unknown) => {\n if (!list.includes(value)) {\n return message ?? `must be one of: ${list.join(', ')}`;\n }\n return null;\n };\n}\n\n/**\n * Value must NOT be in the disallowed list.\n */\nexport function exclusion(list: unknown[], message?: string): Validator {\n return (value: unknown) => {\n if (list.includes(value)) {\n return message ?? `is not allowed`;\n }\n return null;\n };\n}\n\n/**\n * Numeric value must be within min/max.\n */\nexport function rangeValidator(opts: { min?: number; max?: number; message?: string }): Validator {\n return (value: unknown) => {\n const n = Number(value);\n if (opts.min !== undefined && n < opts.min) {\n return opts.message ?? `must be at least ${opts.min}`;\n }\n if (opts.max !== undefined && n > opts.max) {\n return opts.message ?? `must be at most ${opts.max}`;\n }\n return null;\n };\n}\n\n/**\n * Basic email format check.\n */\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\nexport function email(message = 'is not a valid email address'): Validator {\n return (value: unknown) => {\n if (!EMAIL_RE.test(String(value ?? ''))) {\n return message;\n }\n return null;\n };\n}\n","/**\n * @framesquared/data – Store\n *\n * A client-side collection of Model records with sorting, filtering,\n * grouping, events, and sync/change tracking.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { Base, Observable } from '@framesquared/core';\nimport type { Model } from '../Model.js';\nimport { Collection } from './Collection.js';\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface Sorter {\n property: string;\n direction: 'ASC' | 'DESC';\n sorterFn?: (a: Model, b: Model) => number;\n}\n\nexport type FilterOperator = '=' | '!=' | '<' | '<=' | '>' | '>=' | 'like' | 'in' | 'notin';\n\nexport interface Filter {\n property: string;\n value: unknown;\n operator?: FilterOperator;\n filterFn?: (record: Model) => boolean;\n anyMatch?: boolean;\n caseSensitive?: boolean;\n}\n\nexport interface Group {\n name: string;\n children: Model[];\n}\n\nexport interface StoreConfig {\n model: typeof Model;\n data?: Record<string, unknown>[];\n}\n\n// ---------------------------------------------------------------------------\n// Observable bootstrap — install mixin once on Store.prototype\n// ---------------------------------------------------------------------------\n\nconst ObservableMixin: typeof Base = Observable;\n\nfunction ensureObservable(instance: Store): void {\n const proto = ObservableMixin.prototype;\n for (const name of Object.getOwnPropertyNames(proto)) {\n if (name === 'constructor') continue;\n if (name in instance) continue;\n const desc = Object.getOwnPropertyDescriptor(proto, name);\n if (desc && typeof desc.value === 'function') {\n (instance as any)[name] = desc.value.bind(instance);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Filter matching\n// ---------------------------------------------------------------------------\n\nfunction matchFilter(record: Model, f: Filter): boolean {\n if (f.filterFn) return f.filterFn(record);\n\n const fieldValue = record.get(f.property);\n const filterValue = f.value;\n const op = f.operator ?? '=';\n const ci = !(f.caseSensitive ?? false);\n\n switch (op) {\n case '=':\n return fieldValue === filterValue;\n case '!=':\n return fieldValue !== filterValue;\n case '<':\n return (fieldValue as number) < (filterValue as number);\n case '<=':\n return (fieldValue as number) <= (filterValue as number);\n case '>':\n return (fieldValue as number) > (filterValue as number);\n case '>=':\n return (fieldValue as number) >= (filterValue as number);\n case 'like': {\n const sv = ci ? String(fieldValue).toLowerCase() : String(fieldValue);\n const fv = ci ? String(filterValue).toLowerCase() : String(filterValue);\n return sv.includes(fv);\n }\n case 'in':\n return Array.isArray(filterValue) && filterValue.includes(fieldValue);\n case 'notin':\n return Array.isArray(filterValue) && !filterValue.includes(fieldValue);\n default:\n return false;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Sorter comparator builder\n// ---------------------------------------------------------------------------\n\nfunction buildComparator(sorters: Sorter[]): (a: Model, b: Model) => number {\n return (a: Model, b: Model) => {\n for (const sorter of sorters) {\n if (sorter.sorterFn) {\n const result = sorter.sorterFn(a, b);\n if (result !== 0) return result;\n continue;\n }\n const va = a.get(sorter.property) as string | number;\n const vb = b.get(sorter.property) as string | number;\n const dir = sorter.direction === 'DESC' ? -1 : 1;\n if (va < vb) return -1 * dir;\n if (va > vb) return 1 * dir;\n }\n return 0;\n };\n}\n\n// ---------------------------------------------------------------------------\n// Store\n// ---------------------------------------------------------------------------\n\nexport class Store extends Base {\n static override $className = 'Ext.data.Store';\n\n private ModelClass: typeof Model;\n private data: Collection<Model>;\n private allData: Collection<Model>; // unfiltered snapshot\n private currentSorters: Sorter[] = [];\n private currentFilters: Filter[] = [];\n private groupField: string | null = null;\n private groupDirection: 'ASC' | 'DESC' = 'ASC';\n private cachedGroups: Group[] | null = null;\n private removedRecords: Model[] = [];\n\n // Observable state (populated by ensureObservable)\n $destroyHooks: (() => void)[] = [];\n\n constructor(config: StoreConfig) {\n super();\n ensureObservable(this);\n\n this.ModelClass = config.model;\n this.data = new Collection<Model>((r) => r.getId());\n this.allData = new Collection<Model>((r) => r.getId());\n\n if (config.data) {\n this.loadData(config.data);\n }\n }\n\n // -----------------------------------------------------------------------\n // Data loading\n // -----------------------------------------------------------------------\n\n private loadData(rawRecords: Record<string, unknown>[]): void {\n for (const raw of rawRecords) {\n const record = this.ModelClass.create(raw);\n this.data.add(record);\n this.allData.add(record);\n }\n }\n\n // -----------------------------------------------------------------------\n // CRUD\n // -----------------------------------------------------------------------\n\n add(...records: Model[]): Model[] {\n for (const record of records) {\n this.data.add(record);\n this.allData.add(record);\n }\n this.invalidateGroups();\n this.fire('add', this, records);\n this.fire('datachanged', this);\n return records;\n }\n\n insert(index: number, ...records: Model[]): Model[] {\n for (let i = 0; i < records.length; i++) {\n this.data.insert(index + i, records[i]);\n this.allData.add(records[i]);\n }\n this.invalidateGroups();\n this.fire('add', this, records, index);\n this.fire('datachanged', this);\n return records;\n }\n\n remove(...records: Model[]): Model[] {\n const removed: Model[] = [];\n for (const record of records) {\n if (this.data.remove(record)) {\n this.allData.remove(record);\n removed.push(record);\n if (!record.phantom) {\n this.removedRecords.push(record);\n }\n }\n }\n if (removed.length > 0) {\n this.invalidateGroups();\n this.fire('remove', this, removed);\n this.fire('datachanged', this);\n }\n return removed;\n }\n\n removeAt(index: number, count = 1): Model[] {\n const removed = this.data.removeAt(index, count);\n for (const record of removed) {\n this.allData.remove(record);\n if (!record.phantom) {\n this.removedRecords.push(record);\n }\n }\n if (removed.length > 0) {\n this.invalidateGroups();\n this.fire('remove', this, removed);\n this.fire('datachanged', this);\n }\n return removed;\n }\n\n removeAll(silent?: boolean): void {\n this.data.clear();\n this.allData.clear();\n this.invalidateGroups();\n if (!silent) {\n this.fire('clear', this);\n this.fire('datachanged', this);\n }\n }\n\n // -----------------------------------------------------------------------\n // Lookup\n // -----------------------------------------------------------------------\n\n getAt(index: number): Model | undefined {\n return this.data.getAt(index);\n }\n\n getById(id: string | number): Model | undefined {\n return this.data.getByKey(id);\n }\n\n getRange(start?: number, end?: number): Model[] {\n return this.data.getRange(start, end);\n }\n\n getCount(): number {\n return this.data.getCount();\n }\n\n getTotalCount(): number {\n return this.allData.getCount();\n }\n\n indexOf(record: Model): number {\n return this.data.indexOf(record);\n }\n\n contains(record: Model): boolean {\n return this.data.contains(record);\n }\n\n first(): Model | undefined {\n return this.data.first();\n }\n\n last(): Model | undefined {\n return this.data.last();\n }\n\n // eslint-disable-next-line @typescript-eslint/no-invalid-void-type\n each(fn: (record: Model, index: number) => boolean | void): void {\n this.data.each(fn);\n }\n\n collect(fieldName: string): unknown[] {\n const seen = new Set<unknown>();\n this.data.each((r) => {\n seen.add(r.get(fieldName));\n });\n return [...seen];\n }\n\n getData(): Collection<Model> {\n return this.data;\n }\n\n // -----------------------------------------------------------------------\n // Sorting\n // -----------------------------------------------------------------------\n\n sort(fieldOrSorters?: string | Sorter[], direction: 'ASC' | 'DESC' = 'ASC'): void {\n if (typeof fieldOrSorters === 'string') {\n this.currentSorters = [{ property: fieldOrSorters, direction }];\n } else if (Array.isArray(fieldOrSorters)) {\n this.currentSorters = fieldOrSorters;\n }\n\n if (this.currentSorters.length > 0) {\n this.data.sort(buildComparator(this.currentSorters));\n }\n this.invalidateGroups();\n this.fire('sort', this, this.currentSorters);\n }\n\n getSorters(): Sorter[] {\n return [...this.currentSorters];\n }\n\n // -----------------------------------------------------------------------\n // Filtering\n // -----------------------------------------------------------------------\n\n filter(fieldOrFilters: string | Filter[], value?: unknown): void {\n if (typeof fieldOrFilters === 'string') {\n this.currentFilters = [{ property: fieldOrFilters, value }];\n } else {\n this.currentFilters = fieldOrFilters;\n }\n this.applyFilters();\n this.fire('filter', this, this.currentFilters);\n }\n\n clearFilter(suppressEvent?: boolean): void {\n this.currentFilters = [];\n this.applyFilters();\n if (!suppressEvent) {\n this.fire('filter', this, []);\n }\n }\n\n getFilters(): Filter[] {\n return [...this.currentFilters];\n }\n\n private applyFilters(): void {\n if (this.currentFilters.length === 0) {\n // Restore all data\n this.data = new Collection<Model>((r) => r.getId());\n this.allData.each((r) => this.data.add(r));\n } else {\n this.data = new Collection<Model>((r) => r.getId());\n this.allData.each((r) => {\n const passes = this.currentFilters.every((f) => matchFilter(r, f));\n if (passes) this.data.add(r);\n });\n }\n\n // Re-apply sort if active\n if (this.currentSorters.length > 0) {\n this.data.sort(buildComparator(this.currentSorters));\n }\n\n this.invalidateGroups();\n }\n\n // -----------------------------------------------------------------------\n // Grouping\n // -----------------------------------------------------------------------\n\n group(field: string, direction: 'ASC' | 'DESC' = 'ASC'): void {\n this.groupField = field;\n this.groupDirection = direction;\n this.invalidateGroups();\n this.fire('groupchange', this, field, direction);\n }\n\n clearGrouping(): void {\n this.groupField = null;\n this.cachedGroups = null;\n this.fire('groupchange', this, null, null);\n }\n\n isGrouped(): boolean {\n return this.groupField !== null;\n }\n\n getGroups(): Group[] {\n if (!this.groupField) return [];\n if (this.cachedGroups) return this.cachedGroups;\n\n const map = new Map<string, Model[]>();\n this.data.each((r) => {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const key = String(r.get(this.groupField!) ?? '');\n if (!map.has(key)) map.set(key, []);\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n map.get(key)!.push(r);\n });\n\n const groups = [...map.entries()].map(([name, children]) => ({ name, children }));\n const dir = this.groupDirection === 'DESC' ? -1 : 1;\n groups.sort((a, b) => {\n if (a.name < b.name) return -1 * dir;\n if (a.name > b.name) return 1 * dir;\n return 0;\n });\n\n this.cachedGroups = groups;\n return groups;\n }\n\n private invalidateGroups(): void {\n this.cachedGroups = null;\n }\n\n // -----------------------------------------------------------------------\n // Sync / change tracking\n // -----------------------------------------------------------------------\n\n getModifiedRecords(): Model[] {\n const result: Model[] = [];\n this.data.each((r) => {\n if (r.isModified()) result.push(r);\n });\n return result;\n }\n\n getNewRecords(): Model[] {\n const result: Model[] = [];\n this.data.each((r) => {\n if (r.phantom) result.push(r);\n });\n return result;\n }\n\n getRemovedRecords(): Model[] {\n return [...this.removedRecords];\n }\n\n commitChanges(): void {\n this.data.each((r) => {\n if (r.isModified()) r.commit(true);\n });\n this.removedRecords.length = 0;\n }\n\n rejectChanges(): void {\n // Revert modified records\n this.data.each((r) => {\n if (r.isModified()) r.reject(true);\n });\n\n // Re-add removed records\n for (const record of this.removedRecords) {\n this.data.add(record);\n this.allData.add(record);\n }\n this.removedRecords.length = 0;\n this.invalidateGroups();\n }\n\n // -----------------------------------------------------------------------\n // Event helper\n // -----------------------------------------------------------------------\n\n private fire(eventName: string, ...args: unknown[]): void {\n if (typeof (this as any).fireEvent === 'function') {\n (this as any).fireEvent(eventName, ...args);\n }\n }\n}\n","/**\n * @framesquared/data – Collection\n *\n * An ordered, optionally keyed collection used internally by Store.\n * Provides add, insert, remove, sort, find, and iteration.\n */\n\nexport class Collection<T> {\n private items: T[] = [];\n private keyMap: Map<unknown, T> | null = null;\n private keyFn: ((item: T) => unknown) | undefined;\n\n constructor(keyFn?: (item: T) => unknown) {\n this.keyFn = keyFn;\n if (keyFn) {\n this.keyMap = new Map();\n }\n }\n\n getCount(): number {\n return this.items.length;\n }\n\n getAt(index: number): T | undefined {\n return this.items[index];\n }\n\n getByKey(key: unknown): T | undefined {\n return this.keyMap?.get(key);\n }\n\n indexOf(item: T): number {\n return this.items.indexOf(item);\n }\n\n contains(item: T): boolean {\n return this.items.includes(item);\n }\n\n add(item: T): void {\n this.items.push(item);\n if (this.keyFn && this.keyMap) {\n this.keyMap.set(this.keyFn(item), item);\n }\n }\n\n insert(index: number, item: T): void {\n this.items.splice(index, 0, item);\n if (this.keyFn && this.keyMap) {\n this.keyMap.set(this.keyFn(item), item);\n }\n }\n\n remove(item: T): T | undefined {\n const idx = this.items.indexOf(item);\n if (idx === -1) return undefined;\n this.items.splice(idx, 1);\n if (this.keyFn && this.keyMap) {\n this.keyMap.delete(this.keyFn(item));\n }\n return item;\n }\n\n removeAt(index: number, count = 1): T[] {\n const removed = this.items.splice(index, count);\n if (this.keyFn && this.keyMap) {\n for (const item of removed) {\n this.keyMap.delete(this.keyFn(item));\n }\n }\n return removed;\n }\n\n clear(): void {\n this.items.length = 0;\n this.keyMap?.clear();\n }\n\n toArray(): T[] {\n return [...this.items];\n }\n\n // eslint-disable-next-line @typescript-eslint/no-invalid-void-type\n each(fn: (item: T, index: number) => boolean | void): void {\n for (let i = 0; i < this.items.length; i++) {\n if (fn(this.items[i], i) === false) break;\n }\n }\n\n find(fn: (item: T) => boolean): T | undefined {\n return this.items.find(fn);\n }\n\n filter(fn: (item: T) => boolean): T[] {\n return this.items.filter(fn);\n }\n\n sort(compareFn: (a: T, b: T) => number): void {\n this.items.sort(compareFn);\n }\n\n first(): T | undefined {\n return this.items[0];\n }\n\n last(): T | undefined {\n return this.items[this.items.length - 1];\n }\n\n getRange(start = 0, end?: number): T[] {\n return this.items.slice(start, end);\n }\n\n /** Rebuilds the key map (call after sort or external mutation). */\n rekey(): void {\n if (this.keyFn && this.keyMap) {\n this.keyMap.clear();\n for (const item of this.items) {\n this.keyMap.set(this.keyFn(item), item);\n }\n }\n }\n}\n","/**\n * @framesquared/data – ResultSet\n */\n\nimport type { Model } from './Model.js';\n\nexport interface ResultSetConfig {\n records: Model[];\n total?: number;\n success: boolean;\n message?: string;\n}\n\nexport class ResultSet {\n readonly records: Model[];\n readonly total: number;\n readonly success: boolean;\n readonly message: string | undefined;\n\n constructor(config: ResultSetConfig) {\n this.records = config.records;\n this.total = config.total ?? config.records.length;\n this.success = config.success;\n this.message = config.message;\n }\n}\n","/**\n * @framesquared/data – Readers\n *\n * Parse raw server response data into ResultSet instances.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { Model } from '../Model.js';\nimport { ResultSet } from '../ResultSet.js';\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction getNestedValue(obj: any, path: string): unknown {\n const segments = path.split('.');\n let current: any = obj;\n for (const seg of segments) {\n if (current == null || typeof current !== 'object') return undefined;\n current = current[seg];\n }\n return current;\n}\n\n// ---------------------------------------------------------------------------\n// JsonReader\n// ---------------------------------------------------------------------------\n\nexport interface JsonReaderConfig {\n model: typeof Model;\n rootProperty?: string;\n totalProperty?: string;\n successProperty?: string;\n messageProperty?: string;\n}\n\nexport class JsonReader {\n protected config: JsonReaderConfig;\n\n constructor(config: JsonReaderConfig) {\n this.config = config;\n }\n\n read(data: unknown): ResultSet {\n const { model, rootProperty, totalProperty, successProperty, messageProperty } = this.config;\n\n let rawRecords: any[];\n let total: number | undefined;\n let success = true;\n let message: string | undefined;\n\n if (rootProperty) {\n const root = getNestedValue(data, rootProperty);\n rawRecords = Array.isArray(root) ? root : [];\n } else {\n rawRecords = Array.isArray(data) ? data : [];\n }\n\n if (totalProperty && typeof data === 'object' && data !== null) {\n const t = getNestedValue(data, totalProperty);\n if (typeof t === 'number') total = t;\n }\n\n if (successProperty && typeof data === 'object' && data !== null) {\n const s = getNestedValue(data, successProperty);\n if (typeof s === 'boolean') success = s;\n }\n\n if (messageProperty && typeof data === 'object' && data !== null) {\n const m = getNestedValue(data, messageProperty);\n if (typeof m === 'string') message = m;\n }\n\n const records = rawRecords.map((raw) => model.create(raw));\n return new ResultSet({\n records,\n total: total ?? records.length,\n success,\n message,\n });\n }\n}\n\n// ---------------------------------------------------------------------------\n// ArrayReader\n// ---------------------------------------------------------------------------\n\nexport interface ArrayReaderConfig {\n model: typeof Model;\n}\n\nexport class ArrayReader {\n private config: ArrayReaderConfig;\n\n constructor(config: ArrayReaderConfig) {\n this.config = config;\n }\n\n read(data: unknown[][]): ResultSet {\n const { model } = this.config;\n const fieldNames = (model as any).fields.map((f: any) =>\n typeof f === 'string' ? f : f.name,\n ) as string[];\n\n const records = data.map((row) => {\n const obj: Record<string, unknown> = {};\n for (let i = 0; i < fieldNames.length; i++) {\n if (i < row.length) {\n obj[fieldNames[i]] = row[i];\n }\n }\n return model.create(obj);\n });\n\n return new ResultSet({ records, success: true });\n }\n}\n\n// ---------------------------------------------------------------------------\n// XmlReader\n// ---------------------------------------------------------------------------\n\nexport interface XmlReaderConfig {\n model: typeof Model;\n record: string;\n}\n\nexport class XmlReader {\n private config: XmlReaderConfig;\n\n constructor(config: XmlReaderConfig) {\n this.config = config;\n }\n\n read(xmlString: string): ResultSet {\n const { model, record: tagName } = this.config;\n const parser = new DOMParser();\n const doc = parser.parseFromString(xmlString, 'text/xml');\n const nodes = doc.getElementsByTagName(tagName);\n\n const fieldNames = (model as any).fields.map((f: any) =>\n typeof f === 'string' ? f : f.name,\n ) as string[];\n\n const records: Model[] = [];\n for (const node of nodes) {\n const obj: Record<string, unknown> = {};\n for (const fieldName of fieldNames) {\n // Try exact tag match first, then first-letter tag ('n' for 'name')\n let el = node.getElementsByTagName(fieldName)[0];\n if (!el) {\n // Fallback: try single-char abbreviation\n el = node.getElementsByTagName(fieldName[0])[0] as Element;\n }\n if (el) {\n obj[fieldName] = el.textContent ?? '';\n }\n }\n records.push(model.create(obj));\n }\n\n return new ResultSet({ records, success: true });\n }\n}\n","/**\n * @framesquared/data – Writers\n *\n * Serialize Model records for transport to the server.\n */\n\nimport type { Model } from '../Model.js';\n\n// ---------------------------------------------------------------------------\n// JsonWriter\n// ---------------------------------------------------------------------------\n\nexport interface JsonWriterConfig {\n writeAllFields?: boolean;\n allowSingle?: boolean;\n encode?: boolean;\n rootProperty?: string;\n}\n\nexport class JsonWriter {\n private config: JsonWriterConfig;\n\n constructor(config: JsonWriterConfig) {\n this.config = {\n writeAllFields: true,\n allowSingle: false,\n encode: false,\n ...config,\n };\n }\n\n write(records: Model[]): unknown {\n const serialized = records.map((r) => this.serializeRecord(r));\n\n let result: unknown;\n\n // allowSingle: unwrap single-element array\n if (this.config.allowSingle && serialized.length === 1) {\n result = serialized[0];\n } else {\n result = serialized;\n }\n\n // rootProperty: wrap under a key\n if (this.config.rootProperty) {\n result = { [this.config.rootProperty]: result };\n }\n\n // encode: convert to JSON string\n if (this.config.encode) {\n return JSON.stringify(result);\n }\n\n return result;\n }\n\n private serializeRecord(record: Model): Record<string, unknown> {\n if (this.config.writeAllFields) {\n return record.getData({ serialize: true });\n }\n\n // writeAllFields=false: only send changed fields + id\n const Ctor = record.constructor as typeof Model;\n const changes = record.getChanges();\n const result: Record<string, unknown> = {};\n\n // Always include the ID\n const idProp = Ctor.idProperty;\n result[idProp] = record.get(idProp);\n\n // Add changed fields\n for (const [key, value] of Object.entries(changes)) {\n result[key] = value;\n }\n\n return result;\n }\n}\n\n// ---------------------------------------------------------------------------\n// XmlWriter\n// ---------------------------------------------------------------------------\n\nexport interface XmlWriterConfig {\n documentRoot?: string;\n record?: string;\n}\n\nexport class XmlWriter {\n private config: XmlWriterConfig;\n\n constructor(config: XmlWriterConfig) {\n this.config = {\n documentRoot: 'xmlData',\n record: 'record',\n ...config,\n };\n }\n\n write(records: Model[]): string {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const root = this.config.documentRoot!;\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const tag = this.config.record!;\n const parts: string[] = [`<${root}>`];\n\n for (const record of records) {\n parts.push(`<${tag}>`);\n const data = record.getData({ serialize: true });\n for (const [key, value] of Object.entries(data)) {\n parts.push(`<${key}>${escapeXml(String(value ?? ''))}</${key}>`);\n }\n parts.push(`</${tag}>`);\n }\n\n parts.push(`</${root}>`);\n return parts.join('');\n }\n}\n\nfunction escapeXml(str: string): string {\n return str\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&apos;');\n}\n","/**\n * @framesquared/data – Proxy (abstract base)\n */\n\nimport type { Model } from '../Model.js';\nimport type { Operation } from '../Operation.js';\nimport type { ResultSet } from '../ResultSet.js';\n\nexport interface BatchOptions {\n create?: Model[];\n update?: Model[];\n destroy?: Model[];\n}\n\nexport interface Batch {\n success: boolean;\n operations: Operation[];\n}\n\nexport interface ProxyConfig {\n model: typeof Model;\n [key: string]: unknown;\n}\n\nexport abstract class Proxy {\n readonly model: typeof Model;\n\n constructor(config: ProxyConfig) {\n this.model = config.model;\n }\n\n abstract read(operation: Operation, signal?: AbortSignal): Promise<ResultSet>;\n abstract create(operation: Operation): Promise<ResultSet>;\n abstract update(operation: Operation): Promise<ResultSet>;\n abstract destroy(operation: Operation): Promise<ResultSet>;\n\n async batch(options: BatchOptions): Promise<Batch> {\n const { Operation: OpClass } = await import('../Operation.js');\n const operations: Operation[] = [];\n let allSuccess = true;\n\n if (options.create && options.create.length > 0) {\n const op = new OpClass({ action: 'create', records: options.create });\n const rs = await this.create(op);\n op.setResult(rs);\n operations.push(op);\n if (!rs.success) allSuccess = false;\n }\n\n if (options.update && options.update.length > 0) {\n const op = new OpClass({ action: 'update', records: options.update });\n const rs = await this.update(op);\n op.setResult(rs);\n operations.push(op);\n if (!rs.success) allSuccess = false;\n }\n\n if (options.destroy && options.destroy.length > 0) {\n const op = new OpClass({ action: 'destroy', records: options.destroy });\n const rs = await this.destroy(op);\n op.setResult(rs);\n operations.push(op);\n if (!rs.success) allSuccess = false;\n }\n\n return { success: allSuccess, operations };\n }\n}\n","/**\n * @framesquared/data – Client Proxies\n *\n * MemoryProxy, LocalStorageProxy, SessionStorageProxy\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { Operation } from '../Operation.js';\nimport { ResultSet } from '../ResultSet.js';\nimport { Proxy } from './Proxy.js';\nimport type { ProxyConfig } from './Proxy.js';\n\n// ---------------------------------------------------------------------------\n// MemoryProxy\n// ---------------------------------------------------------------------------\n\nexport interface MemoryProxyConfig extends ProxyConfig {\n data?: Record<string, unknown>[];\n}\n\nexport class MemoryProxy extends Proxy {\n private store: Record<string, unknown>[];\n\n constructor(config: MemoryProxyConfig) {\n super(config);\n this.store = config.data ? [...config.data] : [];\n }\n\n async read(operation: Operation): Promise<ResultSet> {\n let data = [...this.store];\n\n // Local filtering\n if (operation.filters && operation.filters.length > 0) {\n data = data.filter((raw) => {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n return operation.filters!.every((f: any) => {\n const fieldVal = raw[f.property];\n const op = f.operator ?? '=';\n switch (op) {\n case '=':\n return fieldVal === f.value;\n case '!=':\n return fieldVal !== f.value;\n case '<':\n return (fieldVal as number) < f.value;\n case '<=':\n return (fieldVal as number) <= f.value;\n case '>':\n return (fieldVal as number) > f.value;\n case '>=':\n return (fieldVal as number) >= f.value;\n default:\n return true;\n }\n });\n });\n }\n\n // Local sorting\n if (operation.sorters && operation.sorters.length > 0) {\n data.sort((a, b) => {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n for (const sorter of operation.sorters!) {\n const va = a[sorter.property] as string | number;\n const vb = b[sorter.property] as string | number;\n const dir = sorter.direction === 'DESC' ? -1 : 1;\n if (va < vb) return -1 * dir;\n if (va > vb) return 1 * dir;\n }\n return 0;\n });\n }\n\n const total = data.length;\n\n // Local paging\n if (operation.start !== undefined || operation.limit !== undefined) {\n const start = operation.start ?? 0;\n const limit = operation.limit ?? data.length;\n data = data.slice(start, start + limit);\n }\n\n const records = data.map((raw) => this.model.create(raw));\n return new ResultSet({ records, total, success: true });\n }\n\n async create(operation: Operation): Promise<ResultSet> {\n for (const record of operation.records) {\n this.store.push(record.getData());\n }\n return new ResultSet({ records: operation.records, success: true });\n }\n\n async update(operation: Operation): Promise<ResultSet> {\n for (const record of operation.records) {\n const id = record.getId();\n const idProp = (this.model as any).idProperty ?? 'id';\n const idx = this.store.findIndex((r) => r[idProp] === id);\n if (idx !== -1) {\n this.store[idx] = record.getData();\n }\n }\n return new ResultSet({ records: operation.records, success: true });\n }\n\n async destroy(operation: Operation): Promise<ResultSet> {\n for (const record of operation.records) {\n const id = record.getId();\n const idProp = (this.model as any).idProperty ?? 'id';\n const idx = this.store.findIndex((r) => r[idProp] === id);\n if (idx !== -1) {\n this.store.splice(idx, 1);\n }\n }\n return new ResultSet({ records: operation.records, success: true });\n }\n}\n\n// ---------------------------------------------------------------------------\n// WebStorageProxy (shared logic for localStorage / sessionStorage)\n// ---------------------------------------------------------------------------\n\nexport interface WebStorageProxyConfig extends ProxyConfig {\n id: string;\n}\n\nabstract class WebStorageProxy extends Proxy {\n protected storageId: string;\n protected abstract getStorage(): Storage;\n\n constructor(config: WebStorageProxyConfig) {\n super(config);\n this.storageId = config.id;\n }\n\n private loadAll(): Record<string, unknown>[] {\n const raw = this.getStorage().getItem(this.storageId);\n if (!raw) return [];\n try {\n return JSON.parse(raw) as Record<string, unknown>[];\n } catch {\n return [];\n }\n }\n\n private saveAll(data: Record<string, unknown>[]): void {\n this.getStorage().setItem(this.storageId, JSON.stringify(data));\n }\n\n async read(_operation: Operation): Promise<ResultSet> {\n const data = this.loadAll();\n const records = data.map((raw) => this.model.create(raw));\n return new ResultSet({ records, success: true });\n }\n\n async create(operation: Operation): Promise<ResultSet> {\n const data = this.loadAll();\n for (const record of operation.records) {\n data.push(record.getData({ serialize: true }));\n }\n this.saveAll(data);\n return new ResultSet({ records: operation.records, success: true });\n }\n\n async update(operation: Operation): Promise<ResultSet> {\n const data = this.loadAll();\n const idProp = (this.model as any).idProperty ?? 'id';\n for (const record of operation.records) {\n const id = record.getId();\n const idx = data.findIndex((r) => r[idProp] === id);\n if (idx !== -1) {\n data[idx] = record.getData({ serialize: true });\n }\n }\n this.saveAll(data);\n return new ResultSet({ records: operation.records, success: true });\n }\n\n async destroy(operation: Operation): Promise<ResultSet> {\n let data = this.loadAll();\n const idProp = (this.model as any).idProperty ?? 'id';\n for (const record of operation.records) {\n const id = record.getId();\n data = data.filter((r) => r[idProp] !== id);\n }\n this.saveAll(data);\n return new ResultSet({ records: operation.records, success: true });\n }\n}\n\n// ---------------------------------------------------------------------------\n// LocalStorageProxy\n// ---------------------------------------------------------------------------\n\nexport class LocalStorageProxy extends WebStorageProxy {\n protected getStorage(): Storage {\n return localStorage;\n }\n}\n\n// ---------------------------------------------------------------------------\n// SessionStorageProxy\n// ---------------------------------------------------------------------------\n\nexport class SessionStorageProxy extends WebStorageProxy {\n protected getStorage(): Storage {\n return sessionStorage;\n }\n}\n","/**\n * @framesquared/data – Server Proxies\n *\n * AjaxProxy (fetch-based) and RestProxy (RESTful URL patterns).\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { Operation } from '../Operation.js';\nimport { ResultSet } from '../ResultSet.js';\nimport { JsonReader } from '../reader/Reader.js';\nimport { JsonWriter } from '../writer/Writer.js';\nimport { Proxy } from './Proxy.js';\nimport type { ProxyConfig } from './Proxy.js';\n\n// ---------------------------------------------------------------------------\n// AjaxProxy\n// ---------------------------------------------------------------------------\n\nexport interface AjaxProxyConfig extends ProxyConfig {\n url: string;\n api?: Partial<Record<string, string>>;\n headers?: Record<string, string>;\n timeout?: number;\n withCredentials?: boolean;\n}\n\nconst ACTION_METHODS: Record<string, string> = {\n read: 'GET',\n create: 'POST',\n update: 'PUT',\n destroy: 'DELETE',\n};\n\nexport class AjaxProxy extends Proxy {\n protected url: string;\n protected api: Partial<Record<string, string>>;\n protected headers: Record<string, string>;\n protected timeout: number;\n protected withCredentials: boolean;\n protected reader: JsonReader;\n protected writer: JsonWriter;\n\n constructor(config: AjaxProxyConfig) {\n super(config);\n this.url = config.url;\n this.api = config.api ?? {};\n this.headers = config.headers ?? {};\n this.timeout = config.timeout ?? 30000;\n this.withCredentials = config.withCredentials ?? false;\n this.reader = new JsonReader({ model: config.model });\n this.writer = new JsonWriter({});\n }\n\n async read(operation: Operation, signal?: AbortSignal): Promise<ResultSet> {\n return this.doRequest(operation, 'read', signal);\n }\n\n async create(operation: Operation): Promise<ResultSet> {\n return this.doRequest(operation, 'create');\n }\n\n async update(operation: Operation): Promise<ResultSet> {\n return this.doRequest(operation, 'update');\n }\n\n async destroy(operation: Operation): Promise<ResultSet> {\n return this.doRequest(operation, 'destroy');\n }\n\n protected buildUrl(operation: Operation, action: string): string {\n const base = this.api[action] ?? this.url;\n const params = { ...operation.params };\n\n // Add paging params\n if (operation.start !== undefined) params.start = operation.start;\n if (operation.limit !== undefined) params.limit = operation.limit;\n if (operation.page !== undefined) params.page = operation.page;\n\n const qs = Object.entries(params)\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`)\n .join('&');\n\n return qs ? `${base}?${qs}` : base;\n }\n\n protected async doRequest(\n operation: Operation,\n action: string,\n signal?: AbortSignal,\n ): Promise<ResultSet> {\n const method = ACTION_METHODS[action] ?? 'GET';\n const url = this.buildUrl(operation, action);\n\n const init: RequestInit = {\n method,\n headers: {\n 'Content-Type': 'application/json',\n ...this.headers,\n },\n credentials: this.withCredentials ? 'include' : 'same-origin',\n signal,\n };\n\n if (method !== 'GET' && operation.records.length > 0) {\n init.body = JSON.stringify(this.writer.write(operation.records));\n }\n\n try {\n const response = await fetch(url, init);\n\n if (!response.ok) {\n let message = `HTTP ${response.status}`;\n try {\n const body = await response.json();\n if (body?.message) message = body.message;\n } catch {\n /* ignore */\n }\n return new ResultSet({ records: [], success: false, message });\n }\n\n const data = await response.json();\n\n // For read, parse through reader\n if (action === 'read') {\n return this.reader.read(data);\n }\n\n // For CUD, build a simple result\n const records = Array.isArray(data)\n ? data.map((d: any) => this.model.create(d))\n : data && typeof data === 'object' && 'id' in data\n ? [this.model.create(data)]\n : operation.records;\n\n return new ResultSet({ records, success: true });\n } catch (err: any) {\n return new ResultSet({\n records: [],\n success: false,\n message: err?.message ?? 'Unknown error',\n });\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// RestProxy\n// ---------------------------------------------------------------------------\n\nexport interface RestProxyConfig extends AjaxProxyConfig {\n appendId?: boolean;\n}\n\nexport class RestProxy extends AjaxProxy {\n private appendId: boolean;\n\n constructor(config: RestProxyConfig) {\n super(config);\n this.appendId = config.appendId ?? true;\n }\n\n protected override buildUrl(operation: Operation, action: string): string {\n let base = this.api[action] ?? this.url;\n\n // Append record ID for single-record operations\n if (this.appendId && action !== 'create' && operation.records.length === 1) {\n const id = operation.records[0].getId();\n if (id !== undefined && id !== null && id !== 0 && id !== '') {\n base = `${base}/${id}`;\n }\n }\n\n // Add query params for read\n const params = { ...operation.params };\n if (operation.start !== undefined) params.start = operation.start;\n if (operation.limit !== undefined) params.limit = operation.limit;\n if (operation.page !== undefined) params.page = operation.page;\n\n const qs = Object.entries(params)\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`)\n .join('&');\n\n return qs ? `${base}?${qs}` : base;\n }\n}\n","/**\n * @framesquared/data – TreeStore\n *\n * Manages hierarchical (tree) data. Records are enhanced with\n * NodeInterface for parent/child navigation, expand/collapse,\n * and nested serialization.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { Base, Observable } from '@framesquared/core';\nimport type { Model } from '../Model.js';\nimport { TreeModel } from '../model/TreeModel.js';\nimport { applyNodeInterface } from '../mixin/NodeInterface.js';\nimport type { NodeInterface } from '../mixin/NodeInterface.js';\n\n// ---------------------------------------------------------------------------\n// Observable bootstrap\n// ---------------------------------------------------------------------------\n\nconst ObservableMixin: typeof Base = Observable;\n\nfunction ensureObservable(instance: any): void {\n const proto = ObservableMixin.prototype;\n for (const name of Object.getOwnPropertyNames(proto)) {\n if (name === 'constructor') continue;\n if (name in instance) continue;\n const desc = Object.getOwnPropertyDescriptor(proto, name);\n if (desc && typeof desc.value === 'function') {\n instance[name] = desc.value.bind(instance);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Config\n// ---------------------------------------------------------------------------\n\nexport interface TreeStoreConfig {\n model?: typeof Model;\n root?: Record<string, unknown>;\n proxy?: any;\n}\n\n// ---------------------------------------------------------------------------\n// TreeStore\n// ---------------------------------------------------------------------------\n\nexport class TreeStore extends Base {\n static override $className = 'Ext.data.TreeStore';\n\n private ModelClass: typeof Model;\n private rootNode!: NodeInterface;\n private nodeMap = new Map<string | number, NodeInterface>();\n\n $destroyHooks: (() => void)[] = [];\n\n constructor(config: TreeStoreConfig) {\n super();\n ensureObservable(this);\n\n this.ModelClass = config.model ?? TreeModel;\n\n if (config.root) {\n this.replaceRoot(this.buildNode(config.root, 0));\n } else {\n // Create an empty root\n const empty = this.ModelClass.create({ id: '__root__', text: 'Root' });\n applyNodeInterface(empty, 0);\n this.replaceRoot(empty as any as NodeInterface);\n }\n }\n\n // -----------------------------------------------------------------------\n // Root\n // -----------------------------------------------------------------------\n\n getRoot(): NodeInterface {\n return this.rootNode;\n }\n\n getRootNode(): NodeInterface {\n return this.rootNode;\n }\n\n /**\n * Replaces the root with new data (or a pre-built node).\n * Fires 'rootchange'.\n */\n setRoot(nodeOrData: NodeInterface | Record<string, unknown>): NodeInterface {\n let node: NodeInterface;\n if (this.isNodeInterface(nodeOrData)) {\n node = nodeOrData;\n } else {\n node = this.buildNode(nodeOrData as Record<string, unknown>, 0);\n }\n this.replaceRoot(node);\n return node;\n }\n\n private isNodeInterface(value: unknown): value is NodeInterface {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'childNodes' in value &&\n 'parentNode' in value &&\n typeof (value as NodeInterface).isRoot === 'function'\n );\n }\n\n private replaceRoot(node: NodeInterface): void {\n this.rootNode = node;\n this.nodeMap.clear();\n this.registerRecursive(node);\n this.fire('rootchange', this, node);\n }\n\n // -----------------------------------------------------------------------\n // Lookup\n // -----------------------------------------------------------------------\n\n getNodeById(id: string | number): NodeInterface | undefined {\n return this.nodeMap.get(id);\n }\n\n // -----------------------------------------------------------------------\n // Tree operations\n // -----------------------------------------------------------------------\n\n appendChild(parent: NodeInterface, child: NodeInterface): void {\n parent.appendChild(child);\n this.registerRecursive(child);\n this.fire('nodeappend', this, child, parent);\n this.fire('datachanged', this);\n }\n\n removeChild(parent: NodeInterface, child: NodeInterface): void {\n parent.removeChild(child);\n this.unregisterRecursive(child);\n this.fire('noderemove', this, child, parent);\n this.fire('datachanged', this);\n }\n\n insertBefore(node: NodeInterface, refNode: NodeInterface): void {\n const parent = refNode.parentNode;\n if (!parent) return;\n parent.insertBefore(node, refNode);\n this.registerRecursive(node);\n this.fire('nodeinsert', this, node, refNode, parent);\n this.fire('datachanged', this);\n }\n\n // -----------------------------------------------------------------------\n // Expand / Collapse\n // -----------------------------------------------------------------------\n\n expandNode(node: NodeInterface): void {\n node.expanded = true;\n node.loaded = true;\n this.fire('nodeexpand', this, node);\n }\n\n collapseNode(node: NodeInterface): void {\n node.expanded = false;\n this.fire('nodecollapse', this, node);\n }\n\n // -----------------------------------------------------------------------\n // Deep search\n // -----------------------------------------------------------------------\n\n findNode(field: string, value: unknown): NodeInterface | undefined {\n return this.findNodeImpl(this.rootNode, field, value);\n }\n\n private findNodeImpl(\n node: NodeInterface,\n field: string,\n value: unknown,\n ): NodeInterface | undefined {\n const model = node as any as { get(f: string): unknown; getId(): unknown };\n const nodeValue = field === 'id' ? model.getId() : model.get(field);\n if (nodeValue === value) return node;\n for (const child of node.childNodes) {\n const found = this.findNodeImpl(child, field, value);\n if (found) return found;\n }\n return undefined;\n }\n\n // -----------------------------------------------------------------------\n // Collapse / Expand all\n // -----------------------------------------------------------------------\n\n collapseAll(): void {\n this.rootNode.cascadeBy((node) => {\n node.expanded = false;\n });\n }\n\n expandAll(): void {\n this.rootNode.cascadeBy((node) => {\n node.expanded = true;\n });\n }\n\n // -----------------------------------------------------------------------\n // Count helpers\n // -----------------------------------------------------------------------\n\n getCount(): number {\n return this.flattenNodes().length;\n }\n\n getTotalCount(): number {\n return this.nodeMap.size;\n }\n\n // -----------------------------------------------------------------------\n // Flatten (for rendering in a flat list / grid)\n // -----------------------------------------------------------------------\n\n flattenNodes(): Model[] {\n const result: Model[] = [];\n this.flattenWalk(this.rootNode, result);\n return result;\n }\n\n private flattenWalk(node: NodeInterface, out: Model[]): void {\n out.push(node as any as Model);\n if (node.expanded || node.isRoot()) {\n for (const child of node.childNodes) {\n this.flattenWalk(child, out);\n }\n }\n }\n\n // -----------------------------------------------------------------------\n // Build tree from nested data\n // -----------------------------------------------------------------------\n\n private buildNode(data: Record<string, unknown>, depth: number): NodeInterface {\n const children = data.children as Record<string, unknown>[] | undefined;\n const expanded = data.expanded as boolean | undefined;\n const nodeData = { ...data };\n delete nodeData.children;\n delete nodeData.expanded;\n\n const model = this.ModelClass.create(nodeData);\n applyNodeInterface(model, depth);\n const node = model as any as NodeInterface;\n\n if (expanded) {\n node.expanded = true;\n node.loaded = true;\n }\n\n if (children && Array.isArray(children)) {\n for (const childData of children) {\n const childNode = this.buildNode(childData, depth + 1);\n node.appendChild(childNode);\n }\n node.loaded = true;\n }\n\n return node;\n }\n\n // -----------------------------------------------------------------------\n // Node registration (for id-based lookup)\n // -----------------------------------------------------------------------\n\n private registerRecursive(node: NodeInterface): void {\n const id = (node as any as Model).getId();\n if (id !== undefined && id !== null) {\n this.nodeMap.set(id, node);\n }\n for (const child of node.childNodes) {\n this.registerRecursive(child);\n }\n }\n\n private unregisterRecursive(node: NodeInterface): void {\n const id = (node as any as Model).getId();\n if (id !== undefined && id !== null) {\n this.nodeMap.delete(id);\n }\n for (const child of node.childNodes) {\n this.unregisterRecursive(child);\n }\n }\n\n // -----------------------------------------------------------------------\n // Event helper\n // -----------------------------------------------------------------------\n\n private fire(eventName: string, ...args: unknown[]): void {\n if (typeof (this as any).fireEvent === 'function') {\n (this as any).fireEvent(eventName, ...args);\n }\n }\n}\n","/**\n * @framesquared/data – NodeInterface\n *\n * Mixin applied to Model instances to give them tree-node capabilities:\n * parent/child/sibling navigation, depth, expand/collapse state,\n * cascadeBy, bubble, getPath, findChild, sort, and nested serialization.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { Model } from '../Model.js';\nimport type { Sorter } from '../store/Store.js';\n\n// ---------------------------------------------------------------------------\n// NodeInterface\n// ---------------------------------------------------------------------------\n\nexport interface NodeInterface extends Model {\n parentNode: NodeInterface | null;\n childNodes: NodeInterface[];\n firstChild: NodeInterface | null;\n lastChild: NodeInterface | null;\n previousSibling: NodeInterface | null;\n nextSibling: NodeInterface | null;\n depth: number;\n\n /** Node state */\n expanded: boolean;\n loaded: boolean;\n\n isLeaf(): boolean;\n isRoot(): boolean;\n isExpanded(): boolean;\n isLoaded(): boolean;\n\n appendChild(child: NodeInterface): void;\n removeChild(child: NodeInterface): void;\n insertBefore(newChild: NodeInterface, refChild: NodeInterface): void;\n\n getPath(separator?: string): string;\n // eslint-disable-next-line @typescript-eslint/no-invalid-void-type\n cascadeBy(fn: (node: NodeInterface) => boolean | void): void;\n // eslint-disable-next-line @typescript-eslint/no-invalid-void-type\n bubble(fn: (node: NodeInterface) => boolean | void): void;\n contains(child: NodeInterface): boolean;\n findChild(field: string, value: unknown, deep?: boolean): NodeInterface | undefined;\n sort(sorters: Sorter[]): void;\n serialize(): any;\n\n // Extended methods\n // eslint-disable-next-line @typescript-eslint/no-invalid-void-type\n eachChild(fn: (child: NodeInterface, index: number) => boolean | void, scope?: object): void;\n indexOf(child: NodeInterface): number;\n getChildAt(index: number): NodeInterface | undefined;\n childCount(): number;\n hasChildNodes(): boolean;\n getChildren(deep?: boolean): NodeInterface[];\n findChildBy(\n // eslint-disable-next-line @typescript-eslint/no-invalid-void-type\n predicate: (node: NodeInterface) => boolean | void,\n deep?: boolean,\n ): NodeInterface | undefined;\n removeAll(): NodeInterface[];\n copy(deep?: boolean): NodeInterface;\n getDepth(): number;\n}\n\n// ---------------------------------------------------------------------------\n// applyNodeInterface — attaches node methods/properties to a model\n// ---------------------------------------------------------------------------\n\nexport function applyNodeInterface(model: Model, depth = 0): void {\n const node = model as any as NodeInterface;\n\n // Properties\n node.parentNode = node.parentNode ?? null;\n node.childNodes = node.childNodes ?? [];\n node.firstChild = node.firstChild ?? null;\n node.lastChild = node.lastChild ?? null;\n node.previousSibling = node.previousSibling ?? null;\n node.nextSibling = node.nextSibling ?? null;\n node.depth = depth;\n node.expanded = node.expanded ?? false;\n node.loaded = node.loaded ?? false;\n\n // Methods\n node.isLeaf = function (): boolean {\n // Explicitly marked as leaf, OR has no children\n if (this.get('leaf') === true) return true;\n return this.childNodes.length === 0;\n };\n\n node.isRoot = function (): boolean {\n return this.parentNode === null;\n };\n\n node.isExpanded = function (): boolean {\n return this.expanded;\n };\n\n node.isLoaded = function (): boolean {\n return this.loaded;\n };\n\n node.appendChild = function (child: NodeInterface): void {\n const c = child as any as NodeInterface;\n\n // Remove from current parent if any\n if (c.parentNode) {\n c.parentNode.removeChild(c);\n }\n\n c.parentNode = this;\n c.depth = this.depth + 1;\n\n const children = this.childNodes;\n const prevLast = children.length > 0 ? children[children.length - 1] : null;\n\n children.push(c);\n\n // Update sibling links\n if (prevLast) {\n prevLast.nextSibling = c;\n c.previousSibling = prevLast;\n } else {\n c.previousSibling = null;\n }\n c.nextSibling = null;\n\n // Update first/last\n this.firstChild = children[0];\n this.lastChild = children[children.length - 1];\n\n // Update depth recursively\n updateDepthRecursive(c, this.depth + 1);\n };\n\n node.removeChild = function (child: NodeInterface): void {\n const children = this.childNodes;\n const idx = children.indexOf(child);\n if (idx === -1) return;\n\n children.splice(idx, 1);\n\n // Update sibling links\n if (child.previousSibling) {\n child.previousSibling.nextSibling = child.nextSibling;\n }\n if (child.nextSibling) {\n child.nextSibling.previousSibling = child.previousSibling;\n }\n\n child.parentNode = null;\n child.previousSibling = null;\n child.nextSibling = null;\n\n // Update first/last\n this.firstChild = children.length > 0 ? children[0] : null;\n this.lastChild = children.length > 0 ? children[children.length - 1] : null;\n };\n\n node.insertBefore = function (newChild: NodeInterface, refChild: NodeInterface): void {\n const children = this.childNodes;\n const refIdx = children.indexOf(refChild);\n if (refIdx === -1) {\n // If ref not found, append\n this.appendChild(newChild);\n return;\n }\n\n // Remove from current parent if any\n if (newChild.parentNode) {\n newChild.parentNode.removeChild(newChild);\n }\n\n newChild.parentNode = this;\n newChild.depth = this.depth + 1;\n\n children.splice(refIdx, 0, newChild);\n\n // Rebuild sibling links for the affected range\n rebuildSiblings(children);\n\n this.firstChild = children[0];\n this.lastChild = children[children.length - 1];\n\n updateDepthRecursive(newChild, this.depth + 1);\n };\n\n node.getPath = function (separator = '/'): string {\n const parts: string[] = [];\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n let current: NodeInterface | null = this;\n while (current) {\n parts.unshift((current.get('text') as string) ?? String(current.getId()));\n current = current.parentNode;\n }\n return separator + parts.join(separator);\n };\n\n // eslint-disable-next-line @typescript-eslint/no-invalid-void-type\n node.cascadeBy = function (fn: (n: NodeInterface) => boolean | void): void {\n cascadeByImpl(this, fn);\n };\n\n // eslint-disable-next-line @typescript-eslint/no-invalid-void-type\n node.bubble = function (fn: (n: NodeInterface) => boolean | void): void {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n let current: NodeInterface | null = this;\n while (current) {\n if (fn(current) === false) return;\n current = current.parentNode;\n }\n };\n\n node.contains = function (descendant: NodeInterface): boolean {\n let current: NodeInterface | null = descendant.parentNode;\n while (current) {\n if (current === (this as any)) return true;\n current = current.parentNode;\n }\n return false;\n };\n\n node.findChild = function (\n field: string,\n value: unknown,\n deep = false,\n ): NodeInterface | undefined {\n for (const child of this.childNodes) {\n if (child.get(field) === value) return child;\n if (deep) {\n const found = child.findChild(field, value, true);\n if (found) return found;\n }\n }\n return undefined;\n };\n\n node.sort = function (sorters: Sorter[]): void {\n this.childNodes.sort((a: NodeInterface, b: NodeInterface) => {\n for (const s of sorters) {\n const va = a.get(s.property) as string | number;\n const vb = b.get(s.property) as string | number;\n const dir = s.direction === 'DESC' ? -1 : 1;\n if (va < vb) return -1 * dir;\n if (va > vb) return 1 * dir;\n }\n return 0;\n });\n rebuildSiblings(this.childNodes);\n this.firstChild = this.childNodes[0] ?? null;\n this.lastChild = this.childNodes[this.childNodes.length - 1] ?? null;\n };\n\n node.serialize = function (): any {\n const data = this.getData();\n if (this.childNodes.length > 0) {\n data.children = this.childNodes.map((c: NodeInterface) => c.serialize());\n }\n return data;\n };\n\n node.eachChild = function (\n // eslint-disable-next-line @typescript-eslint/no-invalid-void-type\n fn: (child: NodeInterface, index: number) => boolean | void,\n ): void {\n for (let i = 0; i < this.childNodes.length; i++) {\n if (fn(this.childNodes[i], i) === false) return;\n }\n };\n\n node.indexOf = function (child: NodeInterface): number {\n return this.childNodes.indexOf(child);\n };\n\n node.getChildAt = function (index: number): NodeInterface | undefined {\n return this.childNodes[index];\n };\n\n node.childCount = function (): number {\n return this.childNodes.length;\n };\n\n node.hasChildNodes = function (): boolean {\n return this.childNodes.length > 0;\n };\n\n node.getChildren = function (deep = false): NodeInterface[] {\n if (!deep) {\n return [...this.childNodes];\n }\n const result: NodeInterface[] = [];\n const collect = (n: NodeInterface): void => {\n for (const child of n.childNodes) {\n result.push(child);\n collect(child);\n }\n };\n collect(this);\n return result;\n };\n\n node.findChildBy = function (\n // eslint-disable-next-line @typescript-eslint/no-invalid-void-type\n predicate: (n: NodeInterface) => boolean | void,\n deep = false,\n ): NodeInterface | undefined {\n for (const child of this.childNodes) {\n const matched = predicate(child);\n if (matched !== false && matched !== undefined && matched !== null) return child;\n if (deep) {\n const found = child.findChildBy(predicate, true);\n if (found) return found;\n }\n }\n return undefined;\n };\n\n node.removeAll = function (): NodeInterface[] {\n const removed = [...this.childNodes];\n for (const child of removed) {\n child.parentNode = null;\n child.previousSibling = null;\n child.nextSibling = null;\n }\n this.childNodes = [];\n this.firstChild = null;\n this.lastChild = null;\n return removed;\n };\n\n node.copy = function (deep = true): NodeInterface {\n const copyCounter = { i: 0 };\n return copyNodeImpl(this, deep, copyCounter);\n };\n\n node.getDepth = function (): number {\n return this.depth;\n };\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction rebuildSiblings(children: NodeInterface[]): void {\n for (let i = 0; i < children.length; i++) {\n children[i].previousSibling = i > 0 ? children[i - 1] : null;\n children[i].nextSibling = i < children.length - 1 ? children[i + 1] : null;\n }\n}\n\nfunction updateDepthRecursive(node: NodeInterface, depth: number): void {\n node.depth = depth;\n for (const child of node.childNodes) {\n updateDepthRecursive(child, depth + 1);\n }\n}\n\n/**\n * Recursively copies a node (and optionally its children) with new IDs.\n */\nfunction copyNodeImpl(node: NodeInterface, deep: boolean, counter: { i: number }): NodeInterface {\n counter.i += 1;\n const newId = 'copy-' + Date.now() + '-' + counter.i;\n const data = (node as any).getData() as Record<string, unknown>;\n const Ctor = (node as any).constructor as { create(data: Record<string, unknown>): any };\n const copyModel = Ctor.create({ ...data, id: newId });\n applyNodeInterface(copyModel, 0);\n const copyNode = copyModel as any as NodeInterface;\n\n if (deep) {\n for (const child of node.childNodes) {\n const childCopy = copyNodeImpl(child, true, counter);\n copyNode.appendChild(childCopy);\n }\n }\n\n return copyNode;\n}\n\n/**\n * Depth-first cascade that returns false if iteration was stopped.\n */\nfunction cascadeByImpl(\n node: NodeInterface,\n // eslint-disable-next-line @typescript-eslint/no-invalid-void-type\n fn: (n: NodeInterface) => boolean | void,\n): boolean {\n if (fn(node) === false) return false;\n for (const child of [...node.childNodes]) {\n if (!cascadeByImpl(child, fn)) return false;\n }\n return true;\n}\n","/**\n * @framesquared/data – TreeModel\n *\n * A convenience Model subclass with NodeInterface pre-applied via create().\n */\n\nimport { Model } from '../Model.js';\nimport { applyNodeInterface } from '../mixin/NodeInterface.js';\nimport type { NodeInterface } from '../mixin/NodeInterface.js';\nimport { FieldType } from '../field/Field.js';\n\nexport class TreeModel extends Model {\n static override $className = 'Ext.data.TreeModel';\n static override idProperty = 'id';\n static defaultRootId = 'root';\n static defaultRootText = 'Root';\n\n static override fields = [\n { name: 'id', type: FieldType.AUTO },\n { name: 'text', type: FieldType.STRING, defaultValue: '' },\n { name: 'leaf', type: FieldType.BOOLEAN, defaultValue: false },\n { name: 'cls', type: FieldType.STRING, defaultValue: '' },\n { name: 'iconCls', type: FieldType.STRING, defaultValue: '' },\n { name: 'icon', type: FieldType.STRING, defaultValue: '' },\n { name: 'href', type: FieldType.STRING, defaultValue: '' },\n { name: 'hrefTarget', type: FieldType.STRING, defaultValue: '' },\n { name: 'qtip', type: FieldType.STRING, defaultValue: '' },\n { name: 'qtitle', type: FieldType.STRING, defaultValue: '' },\n { name: 'allowDrop', type: FieldType.BOOLEAN, defaultValue: true },\n { name: 'allowDrag', type: FieldType.BOOLEAN, defaultValue: true },\n ];\n\n /**\n * Factory method that creates a TreeModel instance with NodeInterface\n * already applied.\n */\n static override create(\n this: typeof Model,\n data?: Record<string, unknown>,\n ): InstanceType<typeof Model> & NodeInterface {\n const instance = super.create(data);\n applyNodeInterface(instance, 0);\n return instance as InstanceType<typeof Model> & NodeInterface;\n }\n}\n","/**\n * @framesquared/data – TreeReader\n *\n * Reads nested (hierarchical) JSON data, flattening it into a ResultSet\n * while preserving the children references.\n */\n\nimport { JsonReader } from './Reader.js';\nimport type { JsonReaderConfig } from './Reader.js';\nimport { ResultSet } from '../ResultSet.js';\n\nexport interface TreeReaderConfig extends JsonReaderConfig {\n /** Name of the property that holds child records. Defaults to 'children'. */\n childrenProperty?: string;\n}\n\nexport class TreeReader extends JsonReader {\n readonly childrenProperty: string;\n\n constructor(config: TreeReaderConfig) {\n super(config);\n this.childrenProperty = config.childrenProperty ?? 'children';\n }\n\n /**\n * Reads data, recursively collecting ALL nodes (at all levels) into a flat\n * ResultSet. The original children references are preserved on the raw\n * objects, so the tree structure is available to callers (e.g. TreeStore).\n */\n override read(data: unknown): ResultSet {\n const flat: Record<string, unknown>[] = [];\n const rootRecords = this.extractRootArray(data);\n this.collectFlat(rootRecords, flat);\n // Build ResultSet directly to avoid rootProperty re-extraction in super.read()\n const model = this.config.model;\n const records = flat.map((raw) => model.create(raw));\n return new ResultSet({ records, total: records.length, success: true });\n }\n\n /**\n * Returns `{ root, records }` where `root` is the first raw record and\n * `records` is the full flat list of all nodes.\n */\n readTree(data: Record<string, unknown>): {\n root: Record<string, unknown>;\n records: Record<string, unknown>[];\n } {\n const flat: Record<string, unknown>[] = [];\n this.collectFlat([data], flat);\n return { root: data, records: flat };\n }\n\n // ---------------------------------------------------------------------------\n // Internal helpers\n // ---------------------------------------------------------------------------\n\n private extractRootArray(data: unknown): Record<string, unknown>[] {\n if (this.config.rootProperty) {\n const root = getNestedValue(data, this.config.rootProperty);\n return Array.isArray(root) ? (root as Record<string, unknown>[]) : [];\n }\n return Array.isArray(data) ? (data as Record<string, unknown>[]) : [];\n }\n\n private collectFlat(items: Record<string, unknown>[], out: Record<string, unknown>[]): void {\n for (const item of items) {\n out.push(item);\n const children = item[this.childrenProperty];\n if (Array.isArray(children) && children.length > 0) {\n this.collectFlat(children as Record<string, unknown>[], out);\n }\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Internal helper (mirrors Reader.ts private helper)\n// ---------------------------------------------------------------------------\n\nfunction getNestedValue(obj: unknown, path: string): unknown {\n const segments = path.split('.');\n let current: unknown = obj;\n for (const seg of segments) {\n if (current == null || typeof current !== 'object') return undefined;\n current = (current as Record<string, unknown>)[seg];\n }\n return current;\n}\n","/**\n * @framesquared/data – TreeWriter\n *\n * Serializes tree nodes (NodeInterface) into nested JSON structures.\n */\n\nimport type { NodeInterface } from '../mixin/NodeInterface.js';\n\nexport interface TreeWriterConfig {\n /** Name of the property used for child records. Defaults to 'children'. */\n childrenProperty?: string;\n}\n\nexport class TreeWriter {\n readonly childrenProperty: string;\n\n constructor(config?: TreeWriterConfig) {\n this.childrenProperty = config?.childrenProperty ?? 'children';\n }\n\n /**\n * Serializes an array of root-level NodeInterface records to plain objects.\n * Children are nested under the configured `childrenProperty`.\n */\n writeRecords(records: NodeInterface[]): Record<string, unknown>[] {\n return records.map((r) => this.writeRecord(r));\n }\n\n private writeRecord(record: NodeInterface): Record<string, unknown> {\n // getData() returns only the declared model fields (persistent field data)\n const data = record.getData() as Record<string, unknown>;\n\n if (record.childNodes && record.childNodes.length > 0) {\n data[this.childrenProperty] = record.childNodes.map((c: NodeInterface) =>\n this.writeRecord(c),\n );\n }\n\n return data;\n }\n}\n","/**\n * @framesquared/data – BufferedStore\n *\n * For large datasets — loads pages of data on demand via a proxy.\n * Uses a sparse page map instead of loading all records.\n * Prefetches adjacent pages based on configurable buffer zones.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { Base, Observable } from '@framesquared/core';\nimport type { Model } from '../Model.js';\nimport { Operation } from '../Operation.js';\n\n// ---------------------------------------------------------------------------\n// Observable bootstrap\n// ---------------------------------------------------------------------------\n\nconst ObservableMixin: typeof Base = Observable;\n\nfunction ensureObservable(instance: any): void {\n const proto = ObservableMixin.prototype;\n for (const name of Object.getOwnPropertyNames(proto)) {\n if (name === 'constructor') continue;\n if (name in instance) continue;\n const desc = Object.getOwnPropertyDescriptor(proto, name);\n if (desc && typeof desc.value === 'function') {\n instance[name] = desc.value.bind(instance);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Config\n// ---------------------------------------------------------------------------\n\nexport interface BufferedStoreConfig {\n model: typeof Model;\n pageSize?: number;\n leadingBufferZone?: number;\n trailingBufferZone?: number;\n proxy?: any;\n}\n\n// ---------------------------------------------------------------------------\n// BufferedStore\n// ---------------------------------------------------------------------------\n\nexport class BufferedStore extends Base {\n static override $className = 'Ext.data.BufferedStore';\n\n private pageSize: number;\n private leadingBufferZone: number;\n private trailingBufferZone: number;\n private proxyRef: any;\n\n /** Page number → array of Model records for that page. */\n private pageMap = new Map<number, Model[]>();\n\n /** Total count from the server. */\n private totalCount = 0;\n\n /** All loaded records in a flat sparse index. */\n private recordMap = new Map<number, Model>();\n\n /** Pages currently being fetched (to avoid duplicate requests). */\n private pendingPages = new Set<number>();\n\n $destroyHooks: (() => void)[] = [];\n\n constructor(config: BufferedStoreConfig) {\n super();\n ensureObservable(this);\n\n this.pageSize = config.pageSize ?? 25;\n this.leadingBufferZone = config.leadingBufferZone ?? 0;\n this.trailingBufferZone = config.trailingBufferZone ?? 0;\n this.proxyRef = config.proxy ?? null;\n }\n\n // -----------------------------------------------------------------------\n // Public API\n // -----------------------------------------------------------------------\n\n getPageSize(): number {\n return this.pageSize;\n }\n\n getCount(): number {\n return this.recordMap.size;\n }\n\n getTotalCount(): number {\n return this.totalCount;\n }\n\n getAt(index: number): Model | undefined {\n return this.recordMap.get(index);\n }\n\n isPageLoaded(pageNumber: number): boolean {\n return this.pageMap.has(pageNumber);\n }\n\n /**\n * Ensures the given range [start, end] of row indices is loaded.\n * Loads missing pages from the proxy and fires 'guaranteedrange'\n * when the requested range is fully available.\n */\n async guaranteeRange(start: number, end: number): Promise<void> {\n const startPage = Math.floor(start / this.pageSize);\n const endPage = Math.floor(end / this.pageSize);\n\n // Collect pages that need loading\n const pagesToLoad: number[] = [];\n for (let p = startPage; p <= endPage; p++) {\n if (!this.pageMap.has(p) && !this.pendingPages.has(p)) {\n pagesToLoad.push(p);\n }\n }\n\n // Load missing pages\n if (pagesToLoad.length > 0) {\n await Promise.all(pagesToLoad.map((p) => this.loadPage(p)));\n }\n\n // Fire event with the records in the requested range\n const records: Model[] = [];\n for (let i = start; i <= end; i++) {\n const rec = this.recordMap.get(i);\n if (rec) records.push(rec);\n }\n this.fire('guaranteedrange', this, records, start, end);\n\n // Prefetch buffer zones (don't await — fire and forget)\n this.prefetchBufferZones(startPage, endPage);\n }\n\n // -----------------------------------------------------------------------\n // Page loading\n // -----------------------------------------------------------------------\n\n private async loadPage(pageNumber: number): Promise<void> {\n if (!this.proxyRef) return;\n if (this.pageMap.has(pageNumber)) return;\n\n this.pendingPages.add(pageNumber);\n\n try {\n const start = pageNumber * this.pageSize;\n const op = new Operation({\n action: 'read',\n start,\n limit: this.pageSize,\n page: pageNumber + 1, // 1-based page for server\n });\n\n const rs = await this.proxyRef.read(op);\n\n if (rs.success) {\n this.pageMap.set(pageNumber, rs.records);\n\n // Index records by their absolute position\n for (let i = 0; i < rs.records.length; i++) {\n this.recordMap.set(start + i, rs.records[i]);\n }\n\n // Update total count from server\n if (rs.total > 0) {\n this.totalCount = rs.total;\n }\n }\n } finally {\n this.pendingPages.delete(pageNumber);\n }\n }\n\n // -----------------------------------------------------------------------\n // Prefetching\n // -----------------------------------------------------------------------\n\n private prefetchBufferZones(startPage: number, endPage: number): void {\n if (this.leadingBufferZone <= 0 && this.trailingBufferZone <= 0) return;\n\n const leadingPages = Math.ceil(this.leadingBufferZone / this.pageSize);\n const trailingPages = Math.ceil(this.trailingBufferZone / this.pageSize);\n\n // Prefetch leading pages (before the requested range)\n for (let p = startPage - leadingPages; p < startPage; p++) {\n if (p >= 0 && !this.pageMap.has(p) && !this.pendingPages.has(p)) {\n this.loadPage(p); // fire and forget\n }\n }\n\n // Prefetch trailing pages (after the requested range)\n const maxPage =\n this.totalCount > 0\n ? Math.floor((this.totalCount - 1) / this.pageSize)\n : endPage + trailingPages;\n\n for (let p = endPage + 1; p <= endPage + trailingPages && p <= maxPage; p++) {\n if (!this.pageMap.has(p) && !this.pendingPages.has(p)) {\n this.loadPage(p); // fire and forget\n }\n }\n }\n\n // -----------------------------------------------------------------------\n // Event helper\n // -----------------------------------------------------------------------\n\n private fire(eventName: string, ...args: unknown[]): void {\n if (typeof (this as any).fireEvent === 'function') {\n (this as any).fireEvent(eventName, ...args);\n }\n }\n}\n","/**\n * @framesquared/data – GraphQLProxy\n *\n * Sends GraphQL queries for read and mutations for CUD operations.\n * Parses response using a rootProperty path into the GraphQL data.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { Operation } from '../Operation.js';\nimport { ResultSet } from '../ResultSet.js';\nimport { Proxy } from './Proxy.js';\nimport type { ProxyConfig } from './Proxy.js';\n\nexport interface GraphQLProxyConfig extends ProxyConfig {\n url: string;\n query?: string;\n mutation?: string;\n rootProperty?: string;\n headers?: Record<string, string>;\n}\n\nexport class GraphQLProxy extends Proxy {\n private url: string;\n private query: string;\n private mutation: string;\n private rootProperty: string;\n private headers: Record<string, string>;\n\n constructor(config: GraphQLProxyConfig) {\n super(config);\n this.url = config.url;\n this.query = config.query ?? '';\n this.mutation = config.mutation ?? '';\n this.rootProperty = config.rootProperty ?? 'data';\n this.headers = config.headers ?? {};\n }\n\n async read(operation: Operation): Promise<ResultSet> {\n return this.doRequest(this.query, operation.params);\n }\n\n async create(operation: Operation): Promise<ResultSet> {\n const variables: Record<string, unknown> = { ...operation.params };\n if (operation.records.length > 0) {\n variables.input = operation.records[0].getData();\n }\n return this.doRequest(this.mutation, variables);\n }\n\n async update(operation: Operation): Promise<ResultSet> {\n const variables: Record<string, unknown> = { ...operation.params };\n if (operation.records.length > 0) {\n variables.input = operation.records[0].getData();\n }\n return this.doRequest(this.mutation, variables);\n }\n\n async destroy(operation: Operation): Promise<ResultSet> {\n const variables: Record<string, unknown> = { ...operation.params };\n if (operation.records.length > 0) {\n variables.id = operation.records[0].getId();\n }\n return this.doRequest(this.mutation, variables);\n }\n\n private async doRequest(\n queryStr: string,\n variables: Record<string, unknown>,\n ): Promise<ResultSet> {\n try {\n const response = await fetch(this.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...this.headers },\n body: JSON.stringify({ query: queryStr, variables }),\n });\n\n const data = await response.json();\n\n // Check for GraphQL errors\n if (data.errors && data.errors.length > 0) {\n return new ResultSet({\n records: [],\n success: false,\n message: data.errors[0].message,\n });\n }\n\n // Extract records from rootProperty path\n const raw = this.extractByPath(data, this.rootProperty);\n const items = Array.isArray(raw) ? raw : raw ? [raw] : [];\n const records = items.map((item: any) => this.model.create(item));\n\n return new ResultSet({ records, success: true });\n } catch (err: any) {\n return new ResultSet({\n records: [],\n success: false,\n message: err?.message ?? 'GraphQL request failed',\n });\n }\n }\n\n private extractByPath(obj: any, path: string): unknown {\n const parts = path.split('.');\n let current = obj;\n for (const part of parts) {\n if (current == null) return undefined;\n current = current[part];\n }\n return current;\n }\n}\n","/**\n * @framesquared/data – WebSocketProxy\n *\n * Maintains a WebSocket connection for real-time data. Sends\n * CRUD operations as JSON messages. Auto-reconnects on disconnect.\n */\n\nimport type { Operation } from '../Operation.js';\nimport { ResultSet } from '../ResultSet.js';\nimport { Proxy } from './Proxy.js';\nimport type { ProxyConfig } from './Proxy.js';\n\nexport interface WebSocketProxyConfig extends ProxyConfig {\n url: string;\n protocol?: string;\n reconnect?: boolean;\n reconnectInterval?: number;\n}\n\nexport class WebSocketProxy extends Proxy {\n private url: string;\n private reconnect: boolean;\n private reconnectInterval: number;\n private ws: WebSocket | null = null;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private listeners: Record<string, ((...args: any[]) => void)[]> = {};\n private intentionalClose = false;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(config: WebSocketProxyConfig) {\n super(config);\n this.url = config.url;\n this.reconnect = config.reconnect ?? false;\n this.reconnectInterval = config.reconnectInterval ?? 3000;\n }\n\n // -----------------------------------------------------------------------\n // Connection management\n // -----------------------------------------------------------------------\n\n connect(): void {\n this.intentionalClose = false;\n this.ws = new WebSocket(this.url);\n\n this.ws.onopen = () => this.fire('open');\n this.ws.onerror = (e) => this.fire('error', e);\n this.ws.onmessage = (e) => {\n try {\n const data = JSON.parse(e.data);\n this.fire('message', data);\n } catch {\n this.fire('message', e.data);\n }\n };\n this.ws.onclose = () => {\n this.fire('close');\n if (this.reconnect && !this.intentionalClose) {\n this.reconnectTimer = setTimeout(() => this.connect(), this.reconnectInterval);\n }\n };\n }\n\n disconnect(): void {\n this.intentionalClose = true;\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n this.ws?.close();\n this.ws = null;\n }\n\n // -----------------------------------------------------------------------\n // Send operations\n // -----------------------------------------------------------------------\n\n send(operation: Operation): void {\n if (!this.ws || this.ws.readyState !== 1) return;\n const message = {\n action: operation.action,\n records: operation.records.map((r) => r.getData()),\n params: operation.params,\n };\n this.ws.send(JSON.stringify(message));\n }\n\n // -----------------------------------------------------------------------\n // Proxy interface (returns empty ResultSets — real data comes via events)\n // -----------------------------------------------------------------------\n\n async read(operation: Operation): Promise<ResultSet> {\n this.send(operation);\n return new ResultSet({ records: [], success: true });\n }\n\n async create(operation: Operation): Promise<ResultSet> {\n this.send(operation);\n return new ResultSet({ records: operation.records, success: true });\n }\n\n async update(operation: Operation): Promise<ResultSet> {\n this.send(operation);\n return new ResultSet({ records: operation.records, success: true });\n }\n\n async destroy(operation: Operation): Promise<ResultSet> {\n this.send(operation);\n return new ResultSet({ records: [], success: true });\n }\n\n // -----------------------------------------------------------------------\n // Events\n // -----------------------------------------------------------------------\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n on(event: string, fn: (...args: any[]) => void): void {\n (this.listeners[event] ??= []).push(fn);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n off(event: string, fn: (...args: any[]) => void): void {\n const list = this.listeners[event];\n if (!list) return;\n const idx = list.indexOf(fn);\n if (idx >= 0) list.splice(idx, 1);\n }\n\n private fire(event: string, ...args: unknown[]): void {\n (this.listeners[event] ?? []).forEach((fn) => fn(...args));\n }\n}\n","/**\n * @framesquared/data – BatchProxy\n *\n * Combines multiple operations into a single HTTP request.\n * Unwraps the batch response into individual ResultSets.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { Operation } from '../Operation.js';\nimport { ResultSet } from '../ResultSet.js';\nimport { Proxy } from './Proxy.js';\nimport type { ProxyConfig } from './Proxy.js';\n\nexport interface BatchProxyConfig extends ProxyConfig {\n url: string;\n headers?: Record<string, string>;\n}\n\nexport class BatchProxy extends Proxy {\n private url: string;\n private headers: Record<string, string>;\n\n constructor(config: BatchProxyConfig) {\n super(config);\n this.url = config.url;\n this.headers = config.headers ?? {};\n }\n\n /**\n * Send multiple operations as a single batched request.\n * Returns an array of ResultSets, one per operation.\n */\n async sendBatch(operations: Operation[]): Promise<ResultSet[]> {\n const body = {\n operations: operations.map((op) => ({\n action: op.action,\n records: op.records.map((r) => r.getData()),\n params: op.params,\n })),\n };\n\n try {\n const response = await fetch(this.url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...this.headers },\n body: JSON.stringify(body),\n });\n\n const data = await response.json();\n const results: ResultSet[] = [];\n\n if (data.results && Array.isArray(data.results)) {\n for (const r of data.results) {\n const records = (r.records ?? []).map((item: any) => this.model.create(item));\n results.push(\n new ResultSet({\n records,\n success: r.success ?? false,\n message: r.message,\n }),\n );\n }\n }\n\n return results;\n } catch (err: any) {\n return operations.map(\n () =>\n new ResultSet({\n records: [],\n success: false,\n message: err?.message ?? 'Batch request failed',\n }),\n );\n }\n }\n\n // Proxy interface — delegate to sendBatch with single operation\n async read(operation: Operation): Promise<ResultSet> {\n const results = await this.sendBatch([operation]);\n return results[0] ?? new ResultSet({ records: [], success: false });\n }\n\n async create(operation: Operation): Promise<ResultSet> {\n const results = await this.sendBatch([operation]);\n return results[0] ?? new ResultSet({ records: [], success: false });\n }\n\n async update(operation: Operation): Promise<ResultSet> {\n const results = await this.sendBatch([operation]);\n return results[0] ?? new ResultSet({ records: [], success: false });\n }\n\n async destroy(operation: Operation): Promise<ResultSet> {\n const results = await this.sendBatch([operation]);\n return results[0] ?? new ResultSet({ records: [], success: false });\n }\n}\n","/**\n * @framesquared/data – Connection\n *\n * Centralized fetch() wrapper. Supports request and response\n * interceptors, default headers, and global error handling.\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\ntype RequestInterceptor = (url: string, init: RequestInit) => [string, RequestInit];\ntype ResponseInterceptor = (response: any) => any;\ntype ErrorHandler = (error: Error) => void;\n\nconst requestInterceptors: RequestInterceptor[] = [];\nconst responseInterceptors: ResponseInterceptor[] = [];\nlet defaultHeaders: Record<string, string> = {};\nlet errorHandler: ErrorHandler | null = null;\n\nexport const Connection = {\n /**\n * Fetch with interceptors and default headers applied.\n */\n async fetch(url: string, init: RequestInit = {}): Promise<any> {\n // Apply default headers\n init.headers = { ...defaultHeaders, ...((init.headers as Record<string, string>) ?? {}) };\n\n // Apply request interceptors\n let currentUrl = url;\n let currentInit = init;\n for (const interceptor of requestInterceptors) {\n [currentUrl, currentInit] = interceptor(currentUrl, currentInit);\n }\n\n try {\n let response = await fetch(currentUrl, currentInit);\n\n // Apply response interceptors\n for (const interceptor of responseInterceptors) {\n response = interceptor(response);\n }\n\n return response;\n } catch (err: any) {\n if (errorHandler) errorHandler(err);\n throw err;\n }\n },\n\n addRequestInterceptor(fn: RequestInterceptor): void {\n requestInterceptors.push(fn);\n },\n\n addResponseInterceptor(fn: ResponseInterceptor): void {\n responseInterceptors.push(fn);\n },\n\n setDefaultHeaders(headers: Record<string, string>): void {\n defaultHeaders = { ...headers };\n },\n\n setErrorHandler(handler: ErrorHandler): void {\n errorHandler = handler;\n },\n\n reset(): void {\n requestInterceptors.length = 0;\n responseInterceptors.length = 0;\n defaultHeaders = {};\n errorHandler = null;\n },\n};\n","/**\n * @framesquared/data – Session\n *\n * Manages a set of related model instances. Tracks all CRUD\n * operations as a unit. save() sends all changes via a BatchProxy.\n * commit()/reject() clear tracked changes.\n */\n\nimport type { Model } from '../Model.js';\nimport { Operation } from '../Operation.js';\nimport type { BatchProxy } from '../proxy/BatchProxy.js';\nimport type { ResultSet } from '../ResultSet.js';\n\nexport interface SessionChanges {\n create: Model[];\n update: Model[];\n destroy: Model[];\n}\n\nexport class Session {\n private created = new Map<unknown, Model>();\n private updated = new Map<unknown, Model>();\n private destroyed = new Map<unknown, Model>();\n\n // -----------------------------------------------------------------------\n // Track operations\n // -----------------------------------------------------------------------\n\n trackCreate(record: Model): void {\n const key = this.recordKey(record);\n this.created.set(key, record);\n }\n\n trackUpdate(record: Model): void {\n const key = this.recordKey(record);\n // If already in created, keep it there (it's still a create)\n if (this.created.has(key)) return;\n this.updated.set(key, record);\n }\n\n trackDestroy(record: Model): void {\n const key = this.recordKey(record);\n // If it was newly created, just remove from created\n if (this.created.has(key)) {\n this.created.delete(key);\n return;\n }\n // Remove from updated if present\n this.updated.delete(key);\n this.destroyed.set(key, record);\n }\n\n // -----------------------------------------------------------------------\n // Accessors\n // -----------------------------------------------------------------------\n\n getCreated(): Model[] {\n return [...this.created.values()];\n }\n getUpdated(): Model[] {\n return [...this.updated.values()];\n }\n getDestroyed(): Model[] {\n return [...this.destroyed.values()];\n }\n\n getChanges(): SessionChanges {\n return {\n create: this.getCreated(),\n update: this.getUpdated(),\n destroy: this.getDestroyed(),\n };\n }\n\n isDirty(): boolean {\n return this.created.size > 0 || this.updated.size > 0 || this.destroyed.size > 0;\n }\n\n // -----------------------------------------------------------------------\n // Save via BatchProxy\n // -----------------------------------------------------------------------\n\n async save(proxy: BatchProxy): Promise<{ success: boolean; results: ResultSet[] }> {\n const ops: Operation[] = [];\n const creates = this.getCreated();\n const updates = this.getUpdated();\n const destroys = this.getDestroyed();\n\n if (creates.length > 0) {\n ops.push(new Operation({ action: 'create', records: creates }));\n }\n if (updates.length > 0) {\n ops.push(new Operation({ action: 'update', records: updates }));\n }\n if (destroys.length > 0) {\n ops.push(new Operation({ action: 'destroy', records: destroys }));\n }\n\n if (ops.length === 0) {\n return { success: true, results: [] };\n }\n\n const results = await proxy.sendBatch(ops);\n const success = results.every((r) => r.success);\n return { success, results };\n }\n\n // -----------------------------------------------------------------------\n // Commit / Reject\n // -----------------------------------------------------------------------\n\n commit(): void {\n this.created.clear();\n this.updated.clear();\n this.destroyed.clear();\n }\n\n reject(): void {\n this.created.clear();\n this.updated.clear();\n this.destroyed.clear();\n }\n\n // -----------------------------------------------------------------------\n // Helpers\n // -----------------------------------------------------------------------\n\n private recordKey(record: Model): unknown {\n // Use record identity (reference) as Map key for dedup\n return record;\n }\n}\n"],"mappings":"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","names":["FieldType","oldValue","Base","Observable","ObservableMixin","Observable","ensureObservable","Base","getNestedValue","Proxy","Proxy","Proxy","Base","Observable","ObservableMixin","Observable","ensureObservable","Base","getNestedValue","Base","Observable","ObservableMixin","Observable","ensureObservable","Base","Proxy","Proxy","Proxy"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@framesquared/data",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Models, stores, and proxies",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -15,7 +15,12 @@
15
15
  "dist"
16
16
  ],
17
17
  "dependencies": {
18
- "@framesquared/core": "0.1.0"
18
+ "@framesquared/core": "0.2.0"
19
+ },
20
+ "license": "MIT",
21
+ "publishConfig": {
22
+ "access": "public",
23
+ "registry": "https://registry.npmjs.org"
19
24
  },
20
25
  "scripts": {
21
26
  "build": "tsup",