velocious 1.0.445 → 1.0.447

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.
Files changed (89) hide show
  1. package/README.md +1 -1
  2. package/build/configuration-types.js +2 -2
  3. package/build/database/pool/async-tracked-multi-connection.js +3 -1
  4. package/build/database/record/index.js +38 -38
  5. package/build/environment-handlers/node/cli/commands/generate/base-models.js +67 -1
  6. package/build/environment-handlers/node/cli/commands/generate/frontend-models.js +169 -0
  7. package/build/frontend-model-controller.js +44 -12
  8. package/build/frontend-model-resource/base-resource.js +519 -129
  9. package/build/frontend-models/base.js +417 -203
  10. package/build/frontend-models/preloader.js +7 -7
  11. package/build/frontend-models/query.js +18 -18
  12. package/build/frontend-models/use-created-event.js +1 -1
  13. package/build/frontend-models/use-destroyed-event.js +1 -1
  14. package/build/frontend-models/use-model-class-event.js +1 -1
  15. package/build/frontend-models/use-updated-event.js +1 -1
  16. package/build/frontend-models/websocket-channel.js +39 -3
  17. package/build/routes/resolver.js +17 -14
  18. package/build/src/configuration-types.d.ts +6 -6
  19. package/build/src/configuration-types.js +3 -3
  20. package/build/src/database/pool/async-tracked-multi-connection.d.ts.map +1 -1
  21. package/build/src/database/pool/async-tracked-multi-connection.js +5 -2
  22. package/build/src/database/record/index.d.ts +38 -38
  23. package/build/src/database/record/index.d.ts.map +1 -1
  24. package/build/src/database/record/index.js +39 -39
  25. package/build/src/environment-handlers/node/cli/commands/generate/base-models.d.ts +13 -0
  26. package/build/src/environment-handlers/node/cli/commands/generate/base-models.d.ts.map +1 -1
  27. package/build/src/environment-handlers/node/cli/commands/generate/base-models.js +59 -2
  28. package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.d.ts +74 -0
  29. package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.d.ts.map +1 -1
  30. package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.js +155 -1
  31. package/build/src/frontend-model-controller.d.ts +2 -1
  32. package/build/src/frontend-model-controller.d.ts.map +1 -1
  33. package/build/src/frontend-model-controller.js +38 -14
  34. package/build/src/frontend-model-resource/base-resource.d.ts +196 -21
  35. package/build/src/frontend-model-resource/base-resource.d.ts.map +1 -1
  36. package/build/src/frontend-model-resource/base-resource.js +467 -112
  37. package/build/src/frontend-models/base.d.ts +232 -149
  38. package/build/src/frontend-models/base.d.ts.map +1 -1
  39. package/build/src/frontend-models/base.js +371 -201
  40. package/build/src/frontend-models/preloader.d.ts +10 -10
  41. package/build/src/frontend-models/preloader.d.ts.map +1 -1
  42. package/build/src/frontend-models/preloader.js +8 -8
  43. package/build/src/frontend-models/query.d.ts +8 -8
  44. package/build/src/frontend-models/query.d.ts.map +1 -1
  45. package/build/src/frontend-models/query.js +19 -19
  46. package/build/src/frontend-models/use-created-event.d.ts +2 -2
  47. package/build/src/frontend-models/use-created-event.d.ts.map +1 -1
  48. package/build/src/frontend-models/use-created-event.js +2 -2
  49. package/build/src/frontend-models/use-destroyed-event.d.ts +1 -1
  50. package/build/src/frontend-models/use-destroyed-event.d.ts.map +1 -1
  51. package/build/src/frontend-models/use-destroyed-event.js +2 -2
  52. package/build/src/frontend-models/use-model-class-event.d.ts +1 -1
  53. package/build/src/frontend-models/use-model-class-event.d.ts.map +1 -1
  54. package/build/src/frontend-models/use-model-class-event.js +2 -2
  55. package/build/src/frontend-models/use-updated-event.d.ts +1 -1
  56. package/build/src/frontend-models/use-updated-event.d.ts.map +1 -1
  57. package/build/src/frontend-models/use-updated-event.js +2 -2
  58. package/build/src/frontend-models/websocket-channel.d.ts +8 -0
  59. package/build/src/frontend-models/websocket-channel.d.ts.map +1 -1
  60. package/build/src/frontend-models/websocket-channel.js +35 -4
  61. package/build/src/routes/resolver.d.ts.map +1 -1
  62. package/build/src/routes/resolver.js +7 -4
  63. package/build/src/utils/model-scope.d.ts +4 -4
  64. package/build/src/utils/model-scope.d.ts.map +1 -1
  65. package/build/src/utils/model-scope.js +3 -3
  66. package/build/src/utils/ransack.d.ts +1 -1
  67. package/build/src/utils/ransack.d.ts.map +1 -1
  68. package/build/src/utils/ransack.js +2 -2
  69. package/build/utils/model-scope.js +2 -2
  70. package/build/utils/ransack.js +1 -1
  71. package/package.json +1 -1
  72. package/src/configuration-types.js +2 -2
  73. package/src/database/pool/async-tracked-multi-connection.js +3 -1
  74. package/src/database/record/index.js +38 -38
  75. package/src/environment-handlers/node/cli/commands/generate/base-models.js +67 -1
  76. package/src/environment-handlers/node/cli/commands/generate/frontend-models.js +169 -0
  77. package/src/frontend-model-controller.js +44 -12
  78. package/src/frontend-model-resource/base-resource.js +519 -129
  79. package/src/frontend-models/base.js +417 -203
  80. package/src/frontend-models/preloader.js +7 -7
  81. package/src/frontend-models/query.js +18 -18
  82. package/src/frontend-models/use-created-event.js +1 -1
  83. package/src/frontend-models/use-destroyed-event.js +1 -1
  84. package/src/frontend-models/use-model-class-event.js +1 -1
  85. package/src/frontend-models/use-updated-event.js +1 -1
  86. package/src/frontend-models/websocket-channel.js +39 -3
  87. package/src/routes/resolver.js +17 -14
  88. package/src/utils/model-scope.js +2 -2
  89. package/src/utils/ransack.js +1 -1
@@ -9,10 +9,10 @@ export class AttributeNotSelectedError extends Error {
9
9
  }
10
10
  /**
11
11
  * Lightweight singular relationship state holder for frontend model instances.
12
- * @template {typeof FrontendModelBase} S
13
- * @template {typeof FrontendModelBase} T
12
+ * @template {FrontendModelClass} S
13
+ * @template {FrontendModelClass} T
14
14
  */
15
- export class FrontendModelSingularRelationship<S extends typeof FrontendModelBase, T extends typeof FrontendModelBase> {
15
+ export class FrontendModelSingularRelationship<S extends FrontendModelClass, T extends FrontendModelClass> {
16
16
  /**
17
17
  * Runs constructor.
18
18
  * @param {InstanceType<S>} model - Parent model.
@@ -50,10 +50,10 @@ export class FrontendModelSingularRelationship<S extends typeof FrontendModelBas
50
50
  }
51
51
  /**
52
52
  * Lightweight has-many relationship state holder for frontend model instances.
53
- * @template {typeof FrontendModelBase} S
54
- * @template {typeof FrontendModelBase} T
53
+ * @template {FrontendModelClass} S
54
+ * @template {FrontendModelClass} T
55
55
  */
56
- export class FrontendModelHasManyRelationship<S extends typeof FrontendModelBase, T extends typeof FrontendModelBase> {
56
+ export class FrontendModelHasManyRelationship<S extends FrontendModelClass, T extends FrontendModelClass> {
57
57
  /**
58
58
  * Runs constructor.
59
59
  * @param {InstanceType<S>} model - Parent model.
@@ -185,8 +185,31 @@ export class FrontendModelAttachmentHandle {
185
185
  model: FrontendModelBase;
186
186
  attachmentName: string;
187
187
  });
188
+ /**
189
+ * Pending attachment inputs queued for the next model save.
190
+ * @type {FrontendModelAttachmentInput[]}
191
+ */
192
+ pendingInputs: FrontendModelAttachmentInput[];
188
193
  model: FrontendModelBase;
189
194
  attachmentName: string;
195
+ /**
196
+ * Queue attachment input for the parent model's next save.
197
+ * @param {FrontendModelAttachmentInput | FrontendModelAttachmentInput[]} input - Attachment input.
198
+ * @returns {void}
199
+ */
200
+ queueAttach(input: FrontendModelAttachmentInput | FrontendModelAttachmentInput[]): void;
201
+ /**
202
+ * Whether this attachment has queued inputs for the next model save.
203
+ * @returns {boolean} Whether any pending inputs exist.
204
+ */
205
+ hasPendingAttachments(): boolean;
206
+ /**
207
+ * Builds the save payload for queued attachment inputs.
208
+ * @returns {Promise<Record<string, ?> | Record<string, ?>[] | undefined>} Normalized attachment payload.
209
+ */
210
+ pendingAttachmentsPayload(): Promise<Record<string, unknown> | Record<string, unknown>[] | undefined>;
211
+ /** Clears queued attachment inputs after a successful model save. */
212
+ clearPendingAttachments(): void;
190
213
  /**
191
214
  * Runs attach.
192
215
  * @param {?} input - Attachment input.
@@ -235,10 +258,10 @@ export default class FrontendModelBase {
235
258
  static setAutoload(newValue: boolean): void;
236
259
  /**
237
260
  * Runs ensure generated attachment methods.
238
- * @this {typeof FrontendModelBase}
261
+ * @this {FrontendModelClass}
239
262
  * @returns {void} - Ensures attachment helper methods exist on the prototype.
240
263
  */
241
- static ensureGeneratedAttachmentMethods(this: typeof FrontendModelBase): void;
264
+ static ensureGeneratedAttachmentMethods(this: FrontendModelClass): void;
242
265
  /**
243
266
  * Runs resource config.
244
267
  * @returns {FrontendModelResourceConfig} - Resource configuration.
@@ -246,103 +269,110 @@ export default class FrontendModelBase {
246
269
  static resourceConfig(): FrontendModelResourceConfig;
247
270
  /**
248
271
  * Runs relationship model classes.
249
- * @this {typeof FrontendModelBase}
250
- * @returns {Record<string, typeof FrontendModelBase | string>} - Relationship model classes (or class name strings) keyed by relationship name.
272
+ * @this {FrontendModelClass}
273
+ * @returns {Record<string, FrontendModelClass | string>} - Relationship model classes (or class name strings) keyed by relationship name.
251
274
  */
252
- static relationshipModelClasses(this: typeof FrontendModelBase): Record<string, typeof FrontendModelBase | string>;
275
+ static relationshipModelClasses(this: FrontendModelClass): Record<string, FrontendModelClass | string>;
253
276
  /**
254
277
  * Register a frontend model class so it can be resolved by name in relationship lookups.
255
- * @param {typeof FrontendModelBase} modelClass - Model class to register.
278
+ * @param {FrontendModelClass} modelClass - Model class to register.
256
279
  * @returns {void}
257
280
  */
258
- static registerModel(modelClass: typeof FrontendModelBase): void;
281
+ static registerModel(modelClass: FrontendModelClass): void;
259
282
  /**
260
283
  * Runs define scope.
261
284
  * @param {(...args: Array<?>) => ?} callback - Scope callback.
262
- * @returns {((...args: Array<?>) => import("./query.js").default<typeof FrontendModelBase>) & {scope: (...args: Array<?>) => import("../utils/model-scope.js").ModelScopeDescriptor}} - Scope helper.
285
+ * @returns {((...args: Array<?>) => import("./query.js").default<FrontendModelClass>) & {scope: (...args: Array<?>) => import("../utils/model-scope.js").ModelScopeDescriptor}} - Scope helper.
263
286
  */
264
- static defineScope(callback: (...args: Array<unknown>) => unknown): ((...args: Array<unknown>) => import("./query.js").default<typeof FrontendModelBase>) & {
287
+ static defineScope(callback: (...args: Array<unknown>) => unknown): ((...args: Array<unknown>) => import("./query.js").default<FrontendModelClass>) & {
265
288
  scope: (...args: Array<unknown>) => import("../utils/model-scope.js").ModelScopeDescriptor;
266
289
  };
267
290
  /**
268
291
  * Resolve a relationship model class value that may be a class reference or a string name.
269
- * @param {typeof FrontendModelBase | string | null | undefined} value - Class or class name.
270
- * @returns {typeof FrontendModelBase | null} - Resolved model class.
292
+ * @param {FrontendModelClass | string | null | undefined} value - Class or class name.
293
+ * @returns {FrontendModelClass | null} - Resolved model class.
271
294
  */
272
- static resolveModelClass(value: typeof FrontendModelBase | string | null | undefined): typeof FrontendModelBase | null;
295
+ static resolveModelClass(value: FrontendModelClass | string | null | undefined): FrontendModelClass | null;
273
296
  /**
274
297
  * Runs relationship definitions.
275
- * @this {typeof FrontendModelBase}
298
+ * @this {FrontendModelClass}
276
299
  * @returns {Record<string, {type: "belongsTo" | "hasOne" | "hasMany", autoload?: boolean}>} - Relationship definitions keyed by relationship name.
277
300
  */
278
- static relationshipDefinitions(this: typeof FrontendModelBase): Record<string, {
301
+ static relationshipDefinitions(this: FrontendModelClass): Record<string, {
279
302
  type: "belongsTo" | "hasOne" | "hasMany";
280
303
  autoload?: boolean;
281
304
  }>;
282
305
  /**
283
306
  * Runs attachment definitions.
284
- * @this {typeof FrontendModelBase}
307
+ * @this {FrontendModelClass}
285
308
  * @returns {Record<string, FrontendModelAttachmentDefinition>} - Attachment definitions keyed by attachment name.
286
309
  */
287
- static attachmentDefinitions(this: typeof FrontendModelBase): Record<string, FrontendModelAttachmentDefinition>;
310
+ static attachmentDefinitions(this: FrontendModelClass): Record<string, FrontendModelAttachmentDefinition>;
288
311
  /**
289
312
  * Runs attachment definition.
290
- * @this {typeof FrontendModelBase}
313
+ * @this {FrontendModelClass}
291
314
  * @param {string} attachmentName - Attachment name.
292
315
  * @returns {FrontendModelAttachmentDefinition | null} - Attachment definition.
293
316
  */
294
- static attachmentDefinition(this: typeof FrontendModelBase, attachmentName: string): FrontendModelAttachmentDefinition | null;
317
+ static attachmentDefinition(this: FrontendModelClass, attachmentName: string): FrontendModelAttachmentDefinition | null;
295
318
  /**
296
319
  * Runs relationship definition.
297
- * @this {typeof FrontendModelBase}
320
+ * @this {FrontendModelClass}
298
321
  * @param {string} relationshipName - Relationship name.
299
322
  * @returns {{type: "belongsTo" | "hasOne" | "hasMany", autoload?: boolean} | null} - Relationship definition.
300
323
  */
301
- static relationshipDefinition(this: typeof FrontendModelBase, relationshipName: string): {
324
+ static relationshipDefinition(this: FrontendModelClass, relationshipName: string): {
302
325
  type: "belongsTo" | "hasOne" | "hasMany";
303
326
  autoload?: boolean;
304
327
  } | null;
328
+ /**
329
+ * Resolves a Rails-style nested attributes key to a configured relationship.
330
+ * @this {FrontendModelClass}
331
+ * @param {string} attributeName - Candidate attribute name, such as `tasksAttributes`.
332
+ * @returns {string | null} Relationship name when nested attributes are configured.
333
+ */
334
+ static nestedAttributesRelationshipName(this: FrontendModelClass, attributeName: string): string | null;
305
335
  /**
306
336
  * Runs relationship model class.
307
- * @this {typeof FrontendModelBase}
337
+ * @this {FrontendModelClass}
308
338
  * @param {string} relationshipName - Relationship name.
309
- * @returns {typeof FrontendModelBase | null} - Target relationship model class.
339
+ * @returns {FrontendModelClass | null} - Target relationship model class.
310
340
  */
311
- static relationshipModelClass(this: typeof FrontendModelBase, relationshipName: string): typeof FrontendModelBase | null;
341
+ static relationshipModelClass(this: FrontendModelClass, relationshipName: string): FrontendModelClass | null;
312
342
  /**
313
343
  * Runs primary key.
314
- * @this {typeof FrontendModelBase}
344
+ * @this {FrontendModelClass}
315
345
  * @returns {string} - Primary key name.
316
346
  */
317
- static primaryKey(this: typeof FrontendModelBase): string;
347
+ static primaryKey(this: FrontendModelClass): string;
318
348
  /**
319
349
  * Runs resource path.
320
- * @this {typeof FrontendModelBase}
350
+ * @this {FrontendModelClass}
321
351
  * @returns {string} - Derived resource path.
322
352
  */
323
- static resourcePath(this: typeof FrontendModelBase): string;
353
+ static resourcePath(this: FrontendModelClass): string;
324
354
  /**
325
355
  * Runs command name.
326
- * @this {typeof FrontendModelBase}
356
+ * @this {FrontendModelClass}
327
357
  * @param {FrontendModelCommandType} commandType - Command type.
328
358
  * @returns {string} - Resolved command name.
329
359
  */
330
- static commandName(this: typeof FrontendModelBase, commandType: FrontendModelCommandType): string;
360
+ static commandName(this: FrontendModelClass, commandType: FrontendModelCommandType): string;
331
361
  /**
332
362
  * Runs normalize custom command payload arguments.
333
- * @this {typeof FrontendModelBase}
363
+ * @this {FrontendModelClass}
334
364
  * @param {Array<?>} args - Command arguments.
335
365
  * @returns {Record<string, ?>} - Command payload.
336
366
  */
337
- static normalizeCustomCommandPayloadArguments(this: typeof FrontendModelBase, args: Array<unknown>): Record<string, unknown>;
367
+ static normalizeCustomCommandPayloadArguments(this: FrontendModelClass, args: Array<unknown>): Record<string, unknown>;
338
368
  /**
339
369
  * Returns the model name, preferring an explicit `static modelName` declaration
340
370
  * over the JavaScript class `.name` property. This allows minified builds to
341
371
  * preserve correct model names without relying on `keep_classnames`.
342
- * @this {typeof FrontendModelBase}
372
+ * @this {FrontendModelClass}
343
373
  * @returns {string} - The model name.
344
374
  */
345
- static getModelName(this: typeof FrontendModelBase): string;
375
+ static getModelName(this: FrontendModelClass): string;
346
376
  /**
347
377
  * Runs configure transport.
348
378
  * @param {FrontendModelTransportConfig} config - Frontend model transport configuration.
@@ -452,18 +482,18 @@ export default class FrontendModelBase {
452
482
  static installWebsocketTestHooks(): void;
453
483
  /**
454
484
  * Runs attributes from response.
455
- * @this {typeof FrontendModelBase}
485
+ * @this {FrontendModelClass}
456
486
  * @param {object} response - Response payload.
457
487
  * @returns {Record<string, ?>} - Attributes from payload.
458
488
  */
459
- static attributesFromResponse(this: typeof FrontendModelBase, response: object): Record<string, unknown>;
489
+ static attributesFromResponse(this: FrontendModelClass, response: object): Record<string, unknown>;
460
490
  /**
461
491
  * Runs model data from response.
462
- * @this {typeof FrontendModelBase}
492
+ * @this {FrontendModelClass}
463
493
  * @param {object} response - Response payload.
464
494
  * @returns {{abilities: Record<string, boolean>, attributes: Record<string, ?>, associationCounts: Record<string, number>, queryData: Record<string, ?>, preloadedRelationships: Record<string, ?>, selectedAttributes: Set<string>}} - Attributes, preloaded relationships, association counts, queryData, abilities, and the selected-attributes set.
465
495
  */
466
- static modelDataFromResponse(this: typeof FrontendModelBase, response: object): {
496
+ static modelDataFromResponse(this: FrontendModelClass, response: object): {
467
497
  abilities: Record<string, boolean>;
468
498
  attributes: Record<string, unknown>;
469
499
  associationCounts: Record<string, number>;
@@ -473,175 +503,175 @@ export default class FrontendModelBase {
473
503
  };
474
504
  /**
475
505
  * Runs apply preloaded relationships.
476
- * @this {typeof FrontendModelBase}
506
+ * @this {FrontendModelClass}
477
507
  * @param {FrontendModelBase} model - Model instance.
478
508
  * @param {Record<string, ?>} preloadedRelationships - Preloaded relationship payload.
479
509
  * @returns {void}
480
510
  */
481
- static applyPreloadedRelationships(this: typeof FrontendModelBase, model: FrontendModelBase, preloadedRelationships: Record<string, unknown>): void;
511
+ static applyPreloadedRelationships(this: FrontendModelClass, model: FrontendModelBase, preloadedRelationships: Record<string, unknown>): void;
482
512
  /**
483
513
  * Runs instantiate relationship value.
484
- * @this {typeof FrontendModelBase}
514
+ * @this {FrontendModelClass}
485
515
  * @param {?} relationshipPayload - Relationship payload value.
486
- * @param {typeof FrontendModelBase | null} targetModelClass - Target model class.
516
+ * @param {FrontendModelClass | null} targetModelClass - Target model class.
487
517
  * @returns {?} - Instantiated relationship value.
488
518
  */
489
- static instantiateRelationshipValue(this: typeof FrontendModelBase, relationshipPayload: unknown, targetModelClass: typeof FrontendModelBase | null): unknown;
519
+ static instantiateRelationshipValue(this: FrontendModelClass, relationshipPayload: unknown, targetModelClass: FrontendModelClass | null): unknown;
490
520
  /**
491
521
  * Runs instantiate from response.
492
- * @template {typeof FrontendModelBase} T
522
+ * @template {FrontendModelClass} T
493
523
  * @this {T}
494
524
  * @param {Record<string, ?> | InstanceType<T>} response - Response payload, or an already-hydrated instance of this class.
495
525
  * @returns {InstanceType<T>} - New model instance, or the same instance unchanged if it was already hydrated.
496
526
  */
497
- static instantiateFromResponse<T extends typeof FrontendModelBase>(this: T, response: Record<string, unknown> | InstanceType<T>): InstanceType<T>;
527
+ static instantiateFromResponse<T extends FrontendModelClass>(this: T, response: Record<string, unknown> | InstanceType<T>): InstanceType<T>;
498
528
  /**
499
529
  * Runs find.
500
- * @template {typeof FrontendModelBase} T
530
+ * @template {FrontendModelClass} T
501
531
  * @this {T}
502
532
  * @param {number | string} id - Record identifier.
503
533
  * @returns {Promise<InstanceType<T>>} - Resolved model.
504
534
  */
505
- static find<T extends typeof FrontendModelBase>(this: T, id: number | string): Promise<InstanceType<T>>;
535
+ static find<T extends FrontendModelClass>(this: T, id: number | string): Promise<InstanceType<T>>;
506
536
  /**
507
537
  * Runs find by.
508
- * @template {typeof FrontendModelBase} T
538
+ * @template {FrontendModelClass} T
509
539
  * @this {T}
510
540
  * @param {Record<string, ?>} conditions - Attribute match conditions.
511
541
  * @returns {Promise<InstanceType<T> | null>} - Found model or null.
512
542
  */
513
- static findBy<T extends typeof FrontendModelBase>(this: T, conditions: Record<string, unknown>): Promise<InstanceType<T> | null>;
543
+ static findBy<T extends FrontendModelClass>(this: T, conditions: Record<string, unknown>): Promise<InstanceType<T> | null>;
514
544
  /**
515
545
  * Runs find by or fail.
516
- * @template {typeof FrontendModelBase} T
546
+ * @template {FrontendModelClass} T
517
547
  * @this {T}
518
548
  * @param {Record<string, ?>} conditions - Attribute match conditions.
519
549
  * @returns {Promise<InstanceType<T>>} - Found model.
520
550
  */
521
- static findByOrFail<T extends typeof FrontendModelBase>(this: T, conditions: Record<string, unknown>): Promise<InstanceType<T>>;
551
+ static findByOrFail<T extends FrontendModelClass>(this: T, conditions: Record<string, unknown>): Promise<InstanceType<T>>;
522
552
  /**
523
553
  * Runs to array.
524
- * @template {typeof FrontendModelBase} T
554
+ * @template {FrontendModelClass} T
525
555
  * @this {T}
526
556
  * @returns {Promise<InstanceType<T>[]>} - Loaded model instances.
527
557
  */
528
- static toArray<T extends typeof FrontendModelBase>(this: T): Promise<InstanceType<T>[]>;
558
+ static toArray<T extends FrontendModelClass>(this: T): Promise<InstanceType<T>[]>;
529
559
  /**
530
560
  * Runs load.
531
- * @template {typeof FrontendModelBase} T
561
+ * @template {FrontendModelClass} T
532
562
  * @this {T}
533
563
  * @returns {Promise<InstanceType<T>[]>} - Loaded model instances.
534
564
  */
535
- static load<T extends typeof FrontendModelBase>(this: T): Promise<InstanceType<T>[]>;
565
+ static load<T extends FrontendModelClass>(this: T): Promise<InstanceType<T>[]>;
536
566
  /**
537
567
  * Runs all.
538
- * @template {typeof FrontendModelBase} T
568
+ * @template {FrontendModelClass} T
539
569
  * @this {T}
540
570
  * @returns {FrontendModelQuery<T>} - Query builder.
541
571
  */
542
- static all<T extends typeof FrontendModelBase>(this: T): FrontendModelQuery<T>;
572
+ static all<T extends FrontendModelClass>(this: T): FrontendModelQuery<T>;
543
573
  /**
544
574
  * Runs where.
545
- * @template {typeof FrontendModelBase} T
575
+ * @template {FrontendModelClass} T
546
576
  * @this {T}
547
577
  * @param {Record<string, ?>} conditions - Root-model where conditions.
548
578
  * @returns {import("./query.js").default<T>} - Query with where conditions.
549
579
  */
550
- static where<T extends typeof FrontendModelBase>(this: T, conditions: Record<string, unknown>): import("./query.js").default<T>;
580
+ static where<T extends FrontendModelClass>(this: T, conditions: Record<string, unknown>): import("./query.js").default<T>;
551
581
  /**
552
582
  * Runs joins.
553
- * @template {typeof FrontendModelBase} T
583
+ * @template {FrontendModelClass} T
554
584
  * @this {T}
555
585
  * @param {Record<string, ?> | Array<Record<string, ?>>} joins - Relationship descriptor joins.
556
586
  * @returns {import("./query.js").default<T>} - Query with joins.
557
587
  */
558
- static joins<T extends typeof FrontendModelBase>(this: T, joins: Record<string, unknown> | Array<Record<string, unknown>>): import("./query.js").default<T>;
588
+ static joins<T extends FrontendModelClass>(this: T, joins: Record<string, unknown> | Array<Record<string, unknown>>): import("./query.js").default<T>;
559
589
  /**
560
590
  * Runs limit.
561
- * @template {typeof FrontendModelBase} T
591
+ * @template {FrontendModelClass} T
562
592
  * @this {T}
563
593
  * @param {number} value - Maximum number of records.
564
594
  * @returns {import("./query.js").default<T>} - Query with limit.
565
595
  */
566
- static limit<T extends typeof FrontendModelBase>(this: T, value: number): import("./query.js").default<T>;
596
+ static limit<T extends FrontendModelClass>(this: T, value: number): import("./query.js").default<T>;
567
597
  /**
568
598
  * Runs offset.
569
- * @template {typeof FrontendModelBase} T
599
+ * @template {FrontendModelClass} T
570
600
  * @this {T}
571
601
  * @param {number} value - Number of records to skip.
572
602
  * @returns {import("./query.js").default<T>} - Query with offset.
573
603
  */
574
- static offset<T extends typeof FrontendModelBase>(this: T, value: number): import("./query.js").default<T>;
604
+ static offset<T extends FrontendModelClass>(this: T, value: number): import("./query.js").default<T>;
575
605
  /**
576
606
  * Runs page.
577
- * @template {typeof FrontendModelBase} T
607
+ * @template {FrontendModelClass} T
578
608
  * @this {T}
579
609
  * @param {number} pageNumber - 1-based page number.
580
610
  * @returns {import("./query.js").default<T>} - Query with page applied.
581
611
  */
582
- static page<T extends typeof FrontendModelBase>(this: T, pageNumber: number): import("./query.js").default<T>;
612
+ static page<T extends FrontendModelClass>(this: T, pageNumber: number): import("./query.js").default<T>;
583
613
  /**
584
614
  * Runs per page.
585
- * @template {typeof FrontendModelBase} T
615
+ * @template {FrontendModelClass} T
586
616
  * @this {T}
587
617
  * @param {number} value - Number of records per page.
588
618
  * @returns {import("./query.js").default<T>} - Query with page size.
589
619
  */
590
- static perPage<T extends typeof FrontendModelBase>(this: T, value: number): import("./query.js").default<T>;
620
+ static perPage<T extends FrontendModelClass>(this: T, value: number): import("./query.js").default<T>;
591
621
  /**
592
622
  * Runs count.
593
- * @template {typeof FrontendModelBase} T
623
+ * @template {FrontendModelClass} T
594
624
  * @this {T}
595
625
  * @returns {Promise<number>} - Number of loaded model instances.
596
626
  */
597
- static count<T extends typeof FrontendModelBase>(this: T): Promise<number>;
627
+ static count<T extends FrontendModelClass>(this: T): Promise<number>;
598
628
  /**
599
629
  * Class-level hook fired when any record of this model is created.
600
630
  * Subscribe-time authorization only — once a subscription is
601
631
  * accepted, future `create` events for this model are delivered
602
632
  * without re-checking per-record visibility. Query options can still
603
633
  * narrow which events reach this callback.
604
- * @this {typeof FrontendModelBase}
605
- * @param {(payload: {id: string, model: InstanceType<typeof FrontendModelBase>}) => void} callback - Event callback.
634
+ * @this {FrontendModelClass}
635
+ * @param {(payload: {id: string, model: FrontendModelBase}) => void} callback - Event callback.
606
636
  * @param {import("./query.js").FrontendModelEventOptions} [options] - Event query or record projection options.
607
637
  * @returns {Promise<() => void>} - Unsubscribe callback.
608
638
  */
609
- static onCreate(this: typeof FrontendModelBase, callback: (payload: {
639
+ static onCreate(this: FrontendModelClass, callback: (payload: {
610
640
  id: string;
611
- model: InstanceType<typeof FrontendModelBase>;
641
+ model: FrontendModelBase;
612
642
  }) => void, options?: import("./query.js").FrontendModelEventOptions): Promise<() => void>;
613
643
  /**
614
644
  * Class-level hook fired when any record of this model is updated.
615
- * @this {typeof FrontendModelBase}
616
- * @param {(payload: {id: string, model: InstanceType<typeof FrontendModelBase>}) => void} callback - Event callback.
645
+ * @this {FrontendModelClass}
646
+ * @param {(payload: {id: string, model: FrontendModelBase}) => void} callback - Event callback.
617
647
  * @param {import("./query.js").FrontendModelEventOptions} [options] - Event query or record projection options.
618
648
  * @returns {Promise<() => void>} - Unsubscribe callback.
619
649
  */
620
- static onUpdate(this: typeof FrontendModelBase, callback: (payload: {
650
+ static onUpdate(this: FrontendModelClass, callback: (payload: {
621
651
  id: string;
622
- model: InstanceType<typeof FrontendModelBase>;
652
+ model: FrontendModelBase;
623
653
  }) => void, options?: import("./query.js").FrontendModelEventOptions): Promise<() => void>;
624
654
  /**
625
655
  * Class-level hook fired when any record of this model is destroyed.
626
- * @this {typeof FrontendModelBase}
656
+ * @this {FrontendModelClass}
627
657
  * @param {(payload: {id: string}) => void} callback - Event callback.
628
658
  * @param {import("./query.js").FrontendModelEventOptions} [options] - Accepted for API symmetry; destroy events carry ids only.
629
659
  * @returns {Promise<() => void>} - Unsubscribe callback.
630
660
  */
631
- static onDestroy(this: typeof FrontendModelBase, callback: (payload: {
661
+ static onDestroy(this: FrontendModelClass, callback: (payload: {
632
662
  id: string;
633
663
  }) => void, options?: import("./query.js").FrontendModelEventOptions): Promise<() => void>;
634
664
  /**
635
665
  * Runs pluck.
636
- * @template {typeof FrontendModelBase} T
666
+ * @template {FrontendModelClass} T
637
667
  * @this {T}
638
668
  * @param {...(string | string[] | Record<string, ?> | Array<Record<string, ?>>)} columns - Pluck definition(s).
639
669
  * @returns {Promise<Array<?>>} - Plucked values.
640
670
  */
641
- static pluck<T extends typeof FrontendModelBase>(this: T, ...columns: (string | string[] | Record<string, unknown> | Array<Record<string, unknown>>)[]): Promise<Array<unknown>>;
671
+ static pluck<T extends FrontendModelClass>(this: T, ...columns: (string | string[] | Record<string, unknown> | Array<Record<string, unknown>>)[]): Promise<Array<unknown>>;
642
672
  /**
643
673
  * Runs search.
644
- * @template {typeof FrontendModelBase} T
674
+ * @template {FrontendModelClass} T
645
675
  * @this {T}
646
676
  * @param {string[]} path - Relationship path.
647
677
  * @param {string} column - Column or attribute name.
@@ -649,167 +679,167 @@ export default class FrontendModelBase {
649
679
  * @param {?} value - Search value.
650
680
  * @returns {FrontendModelQuery<T>} - Query builder with search filter.
651
681
  */
652
- static search<T extends typeof FrontendModelBase>(this: T, path: string[], column: string, operator: "eq" | "like" | "notEq" | "gt" | "gteq" | "lt" | "lteq" | ">" | ">=" | "<" | "<=", value: unknown): FrontendModelQuery<T>;
682
+ static search<T extends FrontendModelClass>(this: T, path: string[], column: string, operator: "eq" | "like" | "notEq" | "gt" | "gteq" | "lt" | "lteq" | ">" | ">=" | "<" | "<=", value: unknown): FrontendModelQuery<T>;
653
683
  /**
654
684
  * Runs ransack.
655
- * @template {typeof FrontendModelBase} T
685
+ * @template {FrontendModelClass} T
656
686
  * @this {T}
657
687
  * @param {Record<string, ?>} params - Ransack-style params hash.
658
688
  * @returns {FrontendModelQuery<T>} - Query builder with Ransack filters applied.
659
689
  */
660
- static ransack<T extends typeof FrontendModelBase>(this: T, params: Record<string, unknown>): FrontendModelQuery<T>;
690
+ static ransack<T extends FrontendModelClass>(this: T, params: Record<string, unknown>): FrontendModelQuery<T>;
661
691
  /**
662
692
  * Runs sort.
663
- * @template {typeof FrontendModelBase} T
693
+ * @template {FrontendModelClass} T
664
694
  * @this {T}
665
695
  * @param {string | string[] | string[][] | [string, string] | Array<[string, string]> | Record<string, ?> | Array<Record<string, ?>>} sort - Sort definition(s).
666
696
  * @returns {FrontendModelQuery<T>} - Query builder with sort definitions.
667
697
  */
668
- static sort<T extends typeof FrontendModelBase>(this: T, sort: string | string[] | string[][] | [string, string] | Array<[string, string]> | Record<string, unknown> | Array<Record<string, unknown>>): FrontendModelQuery<T>;
698
+ static sort<T extends FrontendModelClass>(this: T, sort: string | string[] | string[][] | [string, string] | Array<[string, string]> | Record<string, unknown> | Array<Record<string, unknown>>): FrontendModelQuery<T>;
669
699
  /**
670
700
  * Runs order.
671
- * @template {typeof FrontendModelBase} T
701
+ * @template {FrontendModelClass} T
672
702
  * @this {T}
673
703
  * @param {string | string[] | string[][] | [string, string] | Array<[string, string]> | Record<string, ?> | Array<Record<string, ?>>} sort - Sort definition(s).
674
704
  * @returns {FrontendModelQuery<T>} - Query builder with sort definitions.
675
705
  */
676
- static order<T extends typeof FrontendModelBase>(this: T, sort: string | string[] | string[][] | [string, string] | Array<[string, string]> | Record<string, unknown> | Array<Record<string, unknown>>): FrontendModelQuery<T>;
706
+ static order<T extends FrontendModelClass>(this: T, sort: string | string[] | string[][] | [string, string] | Array<[string, string]> | Record<string, unknown> | Array<Record<string, unknown>>): FrontendModelQuery<T>;
677
707
  /**
678
708
  * Runs group.
679
- * @template {typeof FrontendModelBase} T
709
+ * @template {FrontendModelClass} T
680
710
  * @this {T}
681
711
  * @param {string | string[] | Record<string, ?> | Array<Record<string, ?>>} group - Group definition(s).
682
712
  * @returns {FrontendModelQuery<T>} - Query builder with group definitions.
683
713
  */
684
- static group<T extends typeof FrontendModelBase>(this: T, group: string | string[] | Record<string, unknown> | Array<Record<string, unknown>>): FrontendModelQuery<T>;
714
+ static group<T extends FrontendModelClass>(this: T, group: string | string[] | Record<string, unknown> | Array<Record<string, unknown>>): FrontendModelQuery<T>;
685
715
  /**
686
716
  * Runs distinct.
687
- * @template {typeof FrontendModelBase} T
717
+ * @template {FrontendModelClass} T
688
718
  * @this {T}
689
719
  * @param {boolean} [value] - Whether to request distinct rows.
690
720
  * @returns {FrontendModelQuery<T>} - Query builder with distinct flag.
691
721
  */
692
- static distinct<T extends typeof FrontendModelBase>(this: T, value?: boolean): FrontendModelQuery<T>;
722
+ static distinct<T extends FrontendModelClass>(this: T, value?: boolean): FrontendModelQuery<T>;
693
723
  /**
694
724
  * Runs query.
695
- * @template {typeof FrontendModelBase} T
725
+ * @template {FrontendModelClass} T
696
726
  * @this {T}
697
727
  * @returns {FrontendModelQuery<T>} - Query builder.
698
728
  */
699
- static query<T extends typeof FrontendModelBase>(this: T): FrontendModelQuery<T>;
729
+ static query<T extends FrontendModelClass>(this: T): FrontendModelQuery<T>;
700
730
  /**
701
731
  * Runs preload.
702
- * @template {typeof FrontendModelBase} T
732
+ * @template {FrontendModelClass} T
703
733
  * @this {T}
704
734
  * @param {import("../database/query/index.js").NestedPreloadRecord | string | Array<string | import("../database/query/index.js").NestedPreloadRecord>} preload - Preload graph.
705
735
  * @returns {FrontendModelQuery<T>} - Query with preload.
706
736
  */
707
- static preload<T extends typeof FrontendModelBase>(this: T, preload: import("../database/query/index.js").NestedPreloadRecord | string | Array<string | import("../database/query/index.js").NestedPreloadRecord>): FrontendModelQuery<T>;
737
+ static preload<T extends FrontendModelClass>(this: T, preload: import("../database/query/index.js").NestedPreloadRecord | string | Array<string | import("../database/query/index.js").NestedPreloadRecord>): FrontendModelQuery<T>;
708
738
  /**
709
739
  * Runs select.
710
- * @template {typeof FrontendModelBase} T
740
+ * @template {FrontendModelClass} T
711
741
  * @this {T}
712
742
  * @param {Record<string, string[] | string> | string | string[]} select - Model-aware attribute select map or root-model shorthand.
713
743
  * @returns {FrontendModelQuery<T>} - Query with selected attributes.
714
744
  */
715
- static select<T extends typeof FrontendModelBase>(this: T, select: Record<string, string[] | string> | string | string[]): FrontendModelQuery<T>;
745
+ static select<T extends FrontendModelClass>(this: T, select: Record<string, string[] | string> | string | string[]): FrontendModelQuery<T>;
716
746
  /**
717
747
  * Runs selects extra.
718
- * @template {typeof FrontendModelBase} T
748
+ * @template {FrontendModelClass} T
719
749
  * @this {T}
720
750
  * @param {Record<string, string[] | string> | string | string[]} select - Extra attributes to load in addition to the defaults, keyed by model name or root-model shorthand.
721
751
  * @returns {FrontendModelQuery<T>} - Query with extra selected attributes.
722
752
  */
723
- static selectsExtra<T extends typeof FrontendModelBase>(this: T, select: Record<string, string[] | string> | string | string[]): FrontendModelQuery<T>;
753
+ static selectsExtra<T extends FrontendModelClass>(this: T, select: Record<string, string[] | string> | string | string[]): FrontendModelQuery<T>;
724
754
  /**
725
755
  * Runs first.
726
- * @template {typeof FrontendModelBase} T
756
+ * @template {FrontendModelClass} T
727
757
  * @this {T}
728
758
  * @returns {Promise<InstanceType<T> | null>} - First model or null.
729
759
  */
730
- static first<T extends typeof FrontendModelBase>(this: T): Promise<InstanceType<T> | null>;
760
+ static first<T extends FrontendModelClass>(this: T): Promise<InstanceType<T> | null>;
731
761
  /**
732
762
  * Runs last.
733
- * @template {typeof FrontendModelBase} T
763
+ * @template {FrontendModelClass} T
734
764
  * @this {T}
735
765
  * @returns {Promise<InstanceType<T> | null>} - Last model or null.
736
766
  */
737
- static last<T extends typeof FrontendModelBase>(this: T): Promise<InstanceType<T> | null>;
767
+ static last<T extends FrontendModelClass>(this: T): Promise<InstanceType<T> | null>;
738
768
  /**
739
769
  * Runs find or initialize by.
740
- * @template {typeof FrontendModelBase} T
770
+ * @template {FrontendModelClass} T
741
771
  * @this {T}
742
772
  * @param {Record<string, ?>} conditions - Attribute match conditions.
743
773
  * @returns {Promise<InstanceType<T>>} - Existing or initialized model.
744
774
  */
745
- static findOrInitializeBy<T extends typeof FrontendModelBase>(this: T, conditions: Record<string, unknown>): Promise<InstanceType<T>>;
775
+ static findOrInitializeBy<T extends FrontendModelClass>(this: T, conditions: Record<string, unknown>): Promise<InstanceType<T>>;
746
776
  /**
747
777
  * Runs find or create by.
748
- * @template {typeof FrontendModelBase} T
778
+ * @template {FrontendModelClass} T
749
779
  * @this {T}
750
780
  * @param {Record<string, ?>} conditions - Attribute match conditions.
751
781
  * @param {(model: InstanceType<T>) => Promise<void> | void} [callback] - Optional callback before save when created.
752
782
  * @returns {Promise<InstanceType<T>>} - Existing or newly created model.
753
783
  */
754
- static findOrCreateBy<T extends typeof FrontendModelBase>(this: T, conditions: Record<string, unknown>, callback?: (model: InstanceType<T>) => Promise<void> | void): Promise<InstanceType<T>>;
784
+ static findOrCreateBy<T extends FrontendModelClass>(this: T, conditions: Record<string, unknown>, callback?: (model: InstanceType<T>) => Promise<void> | void): Promise<InstanceType<T>>;
755
785
  /**
756
786
  * Runs create.
757
- * @template {typeof FrontendModelBase} T
787
+ * @template {FrontendModelClass} T
758
788
  * @this {T}
759
789
  * @param {Record<string, ?>} [attributes] - Initial attributes.
760
790
  * @returns {Promise<InstanceType<T>>} - Persisted model.
761
791
  */
762
- static create<T extends typeof FrontendModelBase>(this: T, attributes?: Record<string, unknown>): Promise<InstanceType<T>>;
792
+ static create<T extends FrontendModelClass>(this: T, attributes?: Record<string, unknown>): Promise<InstanceType<T>>;
763
793
  /**
764
794
  * Runs assert find by conditions.
765
- * @this {typeof FrontendModelBase}
795
+ * @this {FrontendModelClass}
766
796
  * @param {Record<string, ?>} conditions - findBy conditions.
767
797
  * @returns {void}
768
798
  */
769
- static assertFindByConditions(this: typeof FrontendModelBase, conditions: Record<string, unknown>): void;
799
+ static assertFindByConditions(this: FrontendModelClass, conditions: Record<string, unknown>): void;
770
800
  /**
771
801
  * Runs matches find by conditions.
772
- * @this {typeof FrontendModelBase}
802
+ * @this {FrontendModelClass}
773
803
  * @param {FrontendModelBase} model - Candidate model.
774
804
  * @param {Record<string, ?>} conditions - Match conditions.
775
805
  * @returns {boolean} - Whether the model matches all conditions.
776
806
  */
777
- static matchesFindByConditions(this: typeof FrontendModelBase, model: FrontendModelBase, conditions: Record<string, unknown>): boolean;
807
+ static matchesFindByConditions(this: FrontendModelClass, model: FrontendModelBase, conditions: Record<string, unknown>): boolean;
778
808
  /**
779
809
  * Runs find by condition value matches.
780
- * @this {typeof FrontendModelBase}
810
+ * @this {FrontendModelClass}
781
811
  * @param {?} actualValue - Actual model value.
782
812
  * @param {?} expectedValue - Expected find condition value.
783
813
  * @returns {boolean} - Whether values match.
784
814
  */
785
- static findByConditionValueMatches(this: typeof FrontendModelBase, actualValue: unknown, expectedValue: unknown): boolean;
815
+ static findByConditionValueMatches(this: FrontendModelClass, actualValue: unknown, expectedValue: unknown): boolean;
786
816
  /**
787
817
  * Runs find by primitive values match.
788
- * @this {typeof FrontendModelBase}
818
+ * @this {FrontendModelClass}
789
819
  * @param {?} actualValue - Actual model value.
790
820
  * @param {?} expectedValue - Expected find condition value.
791
821
  * @returns {boolean} - Whether primitive values match after safe coercion.
792
822
  */
793
- static findByPrimitiveValuesMatch(this: typeof FrontendModelBase, actualValue: unknown, expectedValue: unknown): boolean;
823
+ static findByPrimitiveValuesMatch(this: FrontendModelClass, actualValue: unknown, expectedValue: unknown): boolean;
794
824
  /**
795
825
  * Runs find by numeric string matches number.
796
- * @this {typeof FrontendModelBase}
826
+ * @this {FrontendModelClass}
797
827
  * @param {string} numericString - Numeric string value.
798
828
  * @param {number} expectedNumber - Number value.
799
829
  * @returns {boolean} - Whether values represent the same number.
800
830
  */
801
- static findByNumericStringMatchesNumber(this: typeof FrontendModelBase, numericString: string, expectedNumber: number): boolean;
831
+ static findByNumericStringMatchesNumber(this: FrontendModelClass, numericString: string, expectedNumber: number): boolean;
802
832
  /**
803
833
  * Runs execute command.
804
- * @this {typeof FrontendModelBase}
834
+ * @this {FrontendModelClass}
805
835
  * @param {FrontendModelCommandType} commandType - Command type.
806
836
  * @param {Record<string, ?>} payload - Command payload.
807
837
  * @returns {Promise<Record<string, ?>>} - Parsed JSON response.
808
838
  */
809
- static executeCommand(this: typeof FrontendModelBase, commandType: FrontendModelCommandType, payload: Record<string, unknown>): Promise<Record<string, unknown>>;
839
+ static executeCommand(this: FrontendModelClass, commandType: FrontendModelCommandType, payload: Record<string, unknown>): Promise<Record<string, unknown>>;
810
840
  /**
811
841
  * Runs execute custom command.
812
- * @this {typeof FrontendModelBase}
842
+ * @this {FrontendModelClass}
813
843
  * @param {object} args - Command arguments.
814
844
  * @param {string} args.commandName - Raw command path segment.
815
845
  * @param {FrontendModelRequestCommandType} args.commandType - Logical command type for error handling.
@@ -818,7 +848,7 @@ export default class FrontendModelBase {
818
848
  * @param {string} args.resourcePath - Direct resource path.
819
849
  * @returns {Promise<Record<string, ?>>} - Decoded response payload.
820
850
  */
821
- static executeCustomCommand(this: typeof FrontendModelBase, { commandName, commandType, memberId, payload, resourcePath }: {
851
+ static executeCustomCommand(this: FrontendModelClass, { commandName, commandType, memberId, payload, resourcePath }: {
822
852
  commandName: string;
823
853
  commandType: FrontendModelRequestCommandType;
824
854
  memberId?: string | number | null | undefined;
@@ -827,22 +857,22 @@ export default class FrontendModelBase {
827
857
  }): Promise<Record<string, unknown>>;
828
858
  /**
829
859
  * Runs throw on error frontend model response.
830
- * @this {typeof FrontendModelBase}
860
+ * @this {FrontendModelClass}
831
861
  * @param {object} args - Arguments.
832
862
  * @param {FrontendModelRequestCommandType} args.commandType - Command type.
833
863
  * @param {Record<string, ?>} args.response - Decoded response.
834
864
  * @returns {void}
835
865
  */
836
- static throwOnErrorFrontendModelResponse(this: typeof FrontendModelBase, { commandType, response }: {
866
+ static throwOnErrorFrontendModelResponse(this: FrontendModelClass, { commandType, response }: {
837
867
  commandType: FrontendModelRequestCommandType;
838
868
  response: Record<string, unknown>;
839
869
  }): void;
840
870
  /**
841
871
  * Runs configured frontend model attribute names.
842
- * @this {typeof FrontendModelBase}
872
+ * @this {FrontendModelClass}
843
873
  * @returns {Set<string>} - Configured frontend model attribute names.
844
874
  */
845
- static configuredFrontendModelAttributeNames(this: typeof FrontendModelBase): Set<string>;
875
+ static configuredFrontendModelAttributeNames(this: FrontendModelClass): Set<string>;
846
876
  /**
847
877
  * Runs constructor.
848
878
  * @param {Record<string, ?>} [attributes] - Initial attributes.
@@ -854,12 +884,17 @@ export default class FrontendModelBase {
854
884
  _attributes: Record<string, unknown>;
855
885
  /**
856
886
  * Narrows the runtime value to the documented type.
857
- @type {Record<string, FrontendModelHasManyRelationship<typeof FrontendModelBase, typeof FrontendModelBase> | FrontendModelSingularRelationship<typeof FrontendModelBase, typeof FrontendModelBase>>} */
858
- _relationships: Record<string, FrontendModelHasManyRelationship<typeof FrontendModelBase, typeof FrontendModelBase> | FrontendModelSingularRelationship<typeof FrontendModelBase, typeof FrontendModelBase>>;
887
+ @type {Record<string, FrontendModelHasManyRelationship<FrontendModelClass, FrontendModelClass> | FrontendModelSingularRelationship<FrontendModelClass, FrontendModelClass>>} */
888
+ _relationships: Record<string, FrontendModelHasManyRelationship<FrontendModelClass, FrontendModelClass> | FrontendModelSingularRelationship<FrontendModelClass, FrontendModelClass>>;
859
889
  /**
860
890
  * Narrows the runtime value to the documented type.
861
891
  @type {Record<string, FrontendModelAttachmentHandle>} */
862
892
  _attachments: Record<string, FrontendModelAttachmentHandle>;
893
+ /**
894
+ * Rails-style nested attribute payloads queued for the next save.
895
+ * @type {Record<string, ?>}
896
+ */
897
+ _pendingNestedAttributes: Record<string, unknown>;
863
898
  /**
864
899
  * Narrows the runtime value to the documented type.
865
900
  @type {Set<string> | null} */
@@ -927,9 +962,9 @@ export default class FrontendModelBase {
927
962
  /**
928
963
  * Runs get relationship by name.
929
964
  * @param {string} relationshipName - Relationship name.
930
- * @returns {FrontendModelHasManyRelationship<typeof FrontendModelBase, typeof FrontendModelBase> | FrontendModelSingularRelationship<typeof FrontendModelBase, typeof FrontendModelBase>} - Relationship state object.
965
+ * @returns {FrontendModelHasManyRelationship<FrontendModelClass, FrontendModelClass> | FrontendModelSingularRelationship<FrontendModelClass, FrontendModelClass>} - Relationship state object.
931
966
  */
932
- getRelationshipByName(relationshipName: string): FrontendModelHasManyRelationship<typeof FrontendModelBase, typeof FrontendModelBase> | FrontendModelSingularRelationship<typeof FrontendModelBase, typeof FrontendModelBase>;
967
+ getRelationshipByName(relationshipName: string): FrontendModelHasManyRelationship<FrontendModelClass, FrontendModelClass> | FrontendModelSingularRelationship<FrontendModelClass, FrontendModelClass>;
933
968
  /**
934
969
  * Runs get attachment by name.
935
970
  * @param {string} attachmentName - Attachment name.
@@ -949,11 +984,11 @@ export default class FrontendModelBase {
949
984
  * required columns present are left untouched unless `force` is set. Carries
950
985
  * the query's preload graph, select, selectsExtra, withCount, abilities, and
951
986
  * queryData when re-fetching.
952
- * @param {import("./query.js").default<typeof FrontendModelBase> | import("../database/query/index.js").NestedPreloadRecord | string | Array<string | import("../database/query/index.js").NestedPreloadRecord>} queryOrSpec - Preload source.
987
+ * @param {import("./query.js").default<FrontendModelClass> | import("../database/query/index.js").NestedPreloadRecord | string | Array<string | import("../database/query/index.js").NestedPreloadRecord>} queryOrSpec - Preload source.
953
988
  * @param {{force?: boolean}} [options] - Options.
954
989
  * @returns {Promise<void>} - Resolves when preloading completes.
955
990
  */
956
- preload(queryOrSpec: import("./query.js").default<typeof FrontendModelBase> | import("../database/query/index.js").NestedPreloadRecord | string | Array<string | import("../database/query/index.js").NestedPreloadRecord>, options?: {
991
+ preload(queryOrSpec: import("./query.js").default<FrontendModelClass> | import("../database/query/index.js").NestedPreloadRecord | string | Array<string | import("../database/query/index.js").NestedPreloadRecord>, options?: {
957
992
  force?: boolean;
958
993
  }): Promise<void>;
959
994
  /**
@@ -1094,13 +1129,13 @@ export default class FrontendModelBase {
1094
1129
  * instance's attributes are auto-merged with the broadcast payload
1095
1130
  * before the callback runs, so callers can read fresh values via
1096
1131
  * `this.someAttr()` without re-fetching.
1097
- * @param {(payload: {id: string, model: InstanceType<typeof FrontendModelBase>}) => void} callback - Event callback.
1132
+ * @param {(payload: {id: string, model: FrontendModelBase}) => void} callback - Event callback.
1098
1133
  * @param {import("./query.js").FrontendModelEventOptions} [options] - Event query or record projection options.
1099
1134
  * @returns {Promise<() => void>} - Unsubscribe callback.
1100
1135
  */
1101
1136
  onUpdate(callback: (payload: {
1102
1137
  id: string;
1103
- model: InstanceType<typeof FrontendModelBase>;
1138
+ model: FrontendModelBase;
1104
1139
  }) => void, options?: import("./query.js").FrontendModelEventOptions): Promise<() => void>;
1105
1140
  /**
1106
1141
  * Instance-level hook fired when THIS record is destroyed.
@@ -1149,6 +1184,13 @@ export default class FrontendModelBase {
1149
1184
  * @returns {Promise<void>} - Resolves when destroyed on backend.
1150
1185
  */
1151
1186
  destroy(): Promise<void>;
1187
+ /**
1188
+ * Builds the attachment payload queued on this model for the next save.
1189
+ * @returns {Promise<Record<string, ?>>} Attachment payload keyed by attachment name.
1190
+ */
1191
+ _buildAttachmentsPayload(): Promise<Record<string, unknown>>;
1192
+ /** Clears queued attachment inputs after a successful save. */
1193
+ _clearPendingAttachments(): void;
1152
1194
  /**
1153
1195
  * Walks relationships declared in this resource's `nestedAttributes` config
1154
1196
  * and builds the per-relationship payload of dirty children for a parent save.
@@ -1161,16 +1203,39 @@ export default class FrontendModelBase {
1161
1203
  *
1162
1204
  * Loaded but untouched records are omitted so nested save preserves Rails-style
1163
1205
  * "children not referenced in payload are left alone" semantics.
1164
- * @returns {Record<string, Array<Record<string, ?>>>} - Per-relationship list of nested-attribute entries.
1206
+ * @returns {Promise<Record<string, Array<Record<string, ?>>>>} - Per-relationship list of nested-attribute entries.
1165
1207
  */
1166
- _buildNestedAttributesPayload(): Record<string, Array<Record<string, unknown>>>;
1208
+ _buildNestedAttributesPayload(): Promise<Record<string, Array<Record<string, unknown>>>>;
1167
1209
  /**
1168
1210
  * Builds the payload entry for this child when walked by a parent's
1169
1211
  * `_buildNestedAttributesPayload`. Returns `null` when the child has no
1170
1212
  * dirty state and no dirty descendants, so the parent can omit it.
1171
- * @returns {Record<string, ?> | null} - Nested-attribute entry or null if clean.
1213
+ * @returns {Promise<Record<string, ?> | null>} - Nested-attribute entry or null if clean.
1214
+ */
1215
+ _nestedAttributesEntryForParentSave(): Promise<Record<string, unknown> | null>;
1216
+ /**
1217
+ * Builds nested entries from a Rails-style submitted `*Attributes` value.
1218
+ * @param {FrontendModelClass} ModelClass - Parent model class.
1219
+ * @param {string} relationshipName - Nested relationship name.
1220
+ * @param {?} value - Submitted nested attributes value.
1221
+ * @returns {Promise<Array<Record<string, ?>>>} Nested entries for the transport payload.
1222
+ */
1223
+ _nestedAttributesPayloadForSubmittedValue(ModelClass: FrontendModelClass, relationshipName: string, value: unknown): Promise<Array<Record<string, unknown>>>;
1224
+ /**
1225
+ * Converts one submitted Rails-style nested attributes object into transport payload shape.
1226
+ * @param {FrontendModelClass} ModelClass - Nested child model class.
1227
+ * @param {?} submittedEntry - Submitted nested attributes entry.
1228
+ * @returns {Promise<Record<string, ?>>} Transport nested-attributes entry.
1229
+ */
1230
+ _nestedAttributesEntryPayloadForSubmittedValue(ModelClass: FrontendModelClass, submittedEntry: unknown): Promise<Record<string, unknown>>;
1231
+ /**
1232
+ * Normalizes a submitted attachment value for transport.
1233
+ * @param {FrontendModelClass} ModelClass - Model class owning the attachment.
1234
+ * @param {string} attachmentName - Attachment name.
1235
+ * @param {?} value - Submitted attachment value.
1236
+ * @returns {Promise<Record<string, ?> | Record<string, ?>[]>} Normalized attachment payload.
1172
1237
  */
1173
- _nestedAttributesEntryForParentSave(): Record<string, unknown> | null;
1238
+ _attachmentPayloadForSubmittedValue(ModelClass: FrontendModelClass, attachmentName: string, value: unknown): Promise<Record<string, unknown> | Record<string, unknown>[]>;
1174
1239
  /**
1175
1240
  * After a parent save with `nestedAttributes`, the server response includes
1176
1241
  * preloaded versions of the affected relationships. This replaces the local
@@ -1188,7 +1253,7 @@ export default class FrontendModelBase {
1188
1253
  export type FrontendModelModelEventCallbackEntry = {
1189
1254
  callback: (payload: {
1190
1255
  id: string;
1191
- model: InstanceType<typeof FrontendModelBase>;
1256
+ model: FrontendModelBase;
1192
1257
  }) => void;
1193
1258
  eventFilterKey: string | null;
1194
1259
  eventFilterPayload: import("./query.js").FrontendModelEventFilterPayload | null;
@@ -1216,6 +1281,14 @@ export type FrontendModelRequestCommandType = FrontendModelCommandType | string;
1216
1281
  export type FrontendModelAttachmentDefinition = {
1217
1282
  type: "hasOne" | "hasMany";
1218
1283
  };
1284
+ /**
1285
+ * Attachment input accepted by frontend-model attachment helpers before normalization.
1286
+ */
1287
+ export type FrontendModelAttachmentInput = Record<string, unknown> | {
1288
+ arrayBuffer: () => Promise<ArrayBuffer>;
1289
+ type?: string;
1290
+ name?: string;
1291
+ } | null | undefined;
1219
1292
  /**
1220
1293
  * Defines this typedef.
1221
1294
  */
@@ -1235,6 +1308,16 @@ export type FrontendModelResourceConfig = {
1235
1308
  primaryKey?: string;
1236
1309
  relationships?: string[];
1237
1310
  };
1311
+ /**
1312
+ * Frontend model constructor type.
1313
+ */
1314
+ export type FrontendModelConstructor = {
1315
+ new (attributes?: Record<string, unknown>): FrontendModelBase;
1316
+ };
1317
+ /**
1318
+ * Frontend model static side without generated per-model create overloads.
1319
+ */
1320
+ export type FrontendModelClass = FrontendModelConstructor & Omit<typeof FrontendModelBase, "create">;
1238
1321
  /**
1239
1322
  * FrontendModelTransportConfig type.
1240
1323
  */