@medyll/idae-machine 0.111.0 → 0.112.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/README.md CHANGED
@@ -42,8 +42,10 @@ export const schemeModel = {
42
42
  Après avoir instancié et démarré Machine :
43
43
 
44
44
  ```typescript
45
- import { Machine, schemeModel } from '@medyll/idae-machine';
46
- const machine = new Machine('my-db', 1, schemeModel);
45
+ import { machine, schemeModel } from '@medyll/idae-machine';
46
+
47
+ // Initialisation du singleton
48
+ machine.init({ dbName: 'my-db', version: 1, model: schemeModel });
47
49
  machine.start();
48
50
 
49
51
  // Ajouter un agent
@@ -174,15 +176,15 @@ IndexedDB Abstraction (@medyll/idae-idbql)
174
176
 
175
177
  The recommended way to initialize your app is to use the `Machine` class, which centralizes schema, collections, and IndexedDB access.
176
178
 
179
+
177
180
  ```typescript
178
- import { Machine } from '@medyll/idae-machine';
179
- import { schemeModel } from '@medyll/idae-machine'; // Or your own model
181
+ import { machine, schemeModel } from '@medyll/idae-machine';
180
182
 
181
- // Create and start the machine
182
- const machine = new Machine('my-db', 1, schemeModel);
183
+ // Initialisation du singleton
184
+ machine.init({ dbName: 'my-db', version: 1, model: schemeModel });
183
185
  machine.start();
184
186
 
185
- // Access collections, database, and models
187
+ // Accès aux collections, à la base et au modèle
186
188
  const collections = machine.collections;
187
189
  const idbql = machine.idbql;
188
190
  const idbqlState = machine.idbqlState;
@@ -38,6 +38,28 @@ export type IDbForge = {
38
38
  fieldArgs?: IDbForgeArgs | undefined;
39
39
  is: any;
40
40
  };
41
+ export declare class IDbCollection {
42
+ collection: TplCollectionName;
43
+ _dbCollections: IDbCollections;
44
+ constructor(collection: TplCollectionName, dbCollections: IDbCollections);
45
+ getCollectionModelTemplate(): Tpl;
46
+ getCollectionModelTemplateFks(): {
47
+ [x: string]: {
48
+ code: string;
49
+ multiple: boolean;
50
+ rules: import("@medyll/idae-idbql").CombinedArgs;
51
+ } | undefined;
52
+ };
53
+ getIndexName(): string;
54
+ collectionValues(): IDbCollectionValues<any>;
55
+ collectionFieldValues<T extends Record<string, any>>(data: T): IDbCollectionFieldValues<T>;
56
+ fieldForge<T extends Record<string, any>>(fieldName: keyof T, data: T): IDbCollectionFieldForge<T>;
57
+ getFormValidate(): IDbFormValidate;
58
+ fks(): {
59
+ [collection: string]: Tpl;
60
+ };
61
+ reverseFks(): Record<string, any>;
62
+ }
41
63
  /**
42
64
  * Central class for parsing, introspecting, and extracting metadata from the database schema.
43
65
  * Provides methods to access collections, templates, fields, foreign keys, and type information.
@@ -45,6 +67,22 @@ export type IDbForge = {
45
67
  */
46
68
  export declare class IDbCollections {
47
69
  #private;
70
+ /**
71
+ * Stores shared instances of IDbCollectionValues per collection
72
+ */
73
+ private _collectionValuesMap;
74
+ /**
75
+ * Stores shared instances of IDbCollectionFieldValues per collection+data
76
+ */
77
+ private _collectionFieldValuesMap;
78
+ /**
79
+ * Stores shared instances of IDbCollectionFieldForge per collection, field, and data
80
+ */
81
+ private _collectionFieldForgeMap;
82
+ /**
83
+ * Stores shared instances of IDbFormValidate per collection
84
+ */
85
+ private _formValidateMap;
48
86
  /**
49
87
  * The database model (schema) used for introspection.
50
88
  */
@@ -54,6 +92,7 @@ export declare class IDbCollections {
54
92
  * @param model Optional custom model to use (default: schemeModel)
55
93
  */
56
94
  constructor(model?: IdbqModel);
95
+ get(collection: TplCollectionName): IDbCollection;
57
96
  /**
58
97
  * Parse all collections in the model and return their fields as IDbForge objects.
59
98
  * @returns An object mapping collection names to their parsed fields.
@@ -89,25 +128,48 @@ export declare class IDbCollections {
89
128
  * @param collection The collection name.
90
129
  * @returns The collection object.
91
130
  */
92
- getCollection(collection: TplCollectionName): CollectionModel;
131
+ getCollection(collection: TplCollectionName): CollectionModel; /**
132
+ * Get the collection object from the model.
133
+ * @param collection The collection name.
134
+ * @returns The collection object.
135
+ */
136
+ getCollectionModel(collection: TplCollectionName): CollectionModel;
93
137
  /**
94
138
  * Get the template object for a collection.
95
139
  * @param collection The collection name.
96
140
  * @returns The template object.
97
141
  */
98
- getCollectionTemplate(collection: TplCollectionName): Tpl;
142
+ getCollectionModelTemplate(collection: TplCollectionName): Tpl;
99
143
  /**
100
144
  * Get the foreign keys (fks) object for a collection.
101
145
  * @param collection The collection name.
102
146
  * @returns The fks object.
103
147
  */
104
- getCollectionTemplateFks(collection: TplCollectionName): Tpl["fks"];
148
+ getCollectionModelTemplateFks(collection: TplCollectionName): Tpl["fks"];
105
149
  /**
106
150
  * Get the index field name for a collection.
107
151
  * @param collection The collection name.
108
152
  * @returns The index field name.
109
153
  */
110
- getIndexName(collection: string): string;
154
+ getIndexName(collection: TplCollectionName): string;
155
+ /**
156
+ * Returns a shared instance of IDbCollectionValues for a given collection
157
+ */
158
+ getCollectionValues(collection: TplCollectionName): IDbCollectionValues<any>;
159
+ /**
160
+ * Returns a shared instance of IDbCollectionFieldValues for a given collection and data
161
+ * The instance key is based on the collection and the main index of data (or JSON if missing)
162
+ */
163
+ getCollectionFieldValues<T extends Record<string, any>>(collection: TplCollectionName, data: T): IDbCollectionFieldValues<T>;
164
+ /**
165
+ * Returns a shared instance of IDbCollectionFieldForge for a given collection, field, and data
166
+ * The instance key is based on collection, field, and the main index of data (or JSON if missing)
167
+ */
168
+ getCollectionFieldForge<T extends Record<string, any>>(collection: TplCollectionName, fieldName: keyof T | string, data: T): IDbCollectionFieldForge<T>;
169
+ /**
170
+ * Returns a shared instance of IDbFormValidate for a given collection
171
+ */
172
+ getFormValidate(collection: TplCollectionName): IDbFormValidate;
111
173
  /**
112
174
  * Get the fields object for a collection.
113
175
  * @param collection The collection name.
@@ -194,25 +256,44 @@ export declare class IDbCollections {
194
256
  iterateObjectField(collection: TplCollectionName, fieldName: keyof TplFields, data: Record<string, any>): IDbForge[];
195
257
  }
196
258
  /**
197
- * Utility class to display and format field values for a collection, based on the schema and provided data.
198
- * Used for dynamic UI rendering, presentation, and extracting metadata for form generation.
199
- * @template T The data type for the collection.
259
+ * IDbCollectionValues
260
+ *
261
+ * This class provides utilities to display, format, and introspect field values for a given collection, using the schema and provided data.
262
+ * It is designed for dynamic UI rendering, presentation logic, and metadata extraction for form generation in schema-driven applications.
263
+ *
264
+ * Main responsibilities:
265
+ * - Holds a reference to the collection name and the schema (IDbCollections).
266
+ * - Provides methods to format field values according to their type (number, text, array, object, etc.).
267
+ * - Supplies presentation logic for displaying records (e.g., presentation string, index value).
268
+ * - Offers input attribute generation for forms (inputDataSet).
269
+ * - Supports iteration over array/object fields for advanced UI layouts.
270
+ * - Enables access to field metadata for validation and rendering.
271
+ *
272
+ * Usage:
273
+ * const values = new IDbCollectionValues('agents');
274
+ * const display = values.presentation(agentData); // formatted display string
275
+ * const index = values.indexValue(agentData); // index field value
276
+ * const formatted = values.format('name', agentData); // formatted field value
277
+ * const attrs = values.getInputDataSet('name', agentData); // input attributes for forms
278
+ *
279
+ * This class is typically used via IDbCollections.getCollectionValues for shared instance management.
280
+ * @template T - The type of the data object for the collection.
200
281
  */
201
282
  export declare class IDbCollectionValues<T extends Record<string, any>> {
202
283
  #private;
203
284
  /**
204
285
  * The IDbCollections instance used for schema introspection.
205
286
  */
206
- dbCollections: IDbCollections;
287
+ idbCollections: IDbCollections;
207
288
  /**
208
289
  * The collection name this instance operates on.
209
290
  */
210
- private collection;
291
+ private collectionName;
211
292
  /**
212
293
  * Create a new IDbCollectionValues instance for a given collection.
213
- * @param collection The collection name.
294
+ * @param collectionName The collection name.
214
295
  */
215
- constructor(collection: TplCollectionName);
296
+ constructor(collectionName: TplCollectionName, idbCollections?: IDbCollections);
216
297
  presentation(data: Record<string, any>): string;
217
298
  /**
218
299
  * Get the value of the index field for a data object.
@@ -256,15 +337,37 @@ export declare class IDbCollectionFieldValues<T extends Record<string, any>> {
256
337
  * @param fieldName The field name to introspect.
257
338
  */
258
339
  getForge(fieldName: keyof T): IDbForge | undefined;
259
- constructor(collection: TplCollectionName, data: T);
340
+ constructor(collection: TplCollectionName, data: T, collectionValues?: IDbCollectionValues<T>);
260
341
  format(fieldName: keyof T): string | string[];
261
342
  getInputDataSet(fieldName: keyof T): Record<"data-collection" | "data-fieldName" | "data-fieldType" | "data-fieldArgs" | "data-collectionId", string>;
262
343
  iterateArray(fieldName: string, data: any[]): IDbForge[];
263
344
  iterateObject(fieldName: string, data: Record<string, any>): IDbForge[];
264
345
  }
346
+ /**
347
+ * IDbCollectionFieldForge
348
+ *
349
+ * This class provides advanced metadata and formatting for a single field of a collection, given a data object.
350
+ * It is designed for dynamic UI generation, form rendering, and introspection in schema-driven applications.
351
+ *
352
+ * Main responsibilities:
353
+ * - Holds references to the collection name, field name, and the data object for context.
354
+ * - Provides access to the parsed field metadata (IDbForge) for the field, including type, rules, and arguments.
355
+ * - Offers formatting utilities for the field value, adapting to type (number, text, array, object, etc.).
356
+ * - Supplies input attributes and type hints for form generation (e.g., htmlInputType, inputDataSet).
357
+ * - Supports iteration over array/object fields for complex form layouts.
358
+ * - Enables extraction of raw data and field arguments for validation and UI logic.
359
+ *
360
+ * Usage:
361
+ * const forge = new IDbCollectionFieldForge('agents', 'name', agentData);
362
+ * const formatted = forge.format; // formatted value for display
363
+ * const inputType = forge.htmlInputType; // e.g. 'text', 'area', 'email', etc.
364
+ * const meta = forge.forge; // IDbForge metadata for the field
365
+ *
366
+ * This class is typically used via IDbCollections.getCollectionFieldForge for shared instance management.
367
+ */
265
368
  export declare class IDbCollectionFieldForge<T extends Record<string, any>> {
266
369
  #private;
267
- constructor(collection: TplCollectionName, fieldName: any, data: T);
370
+ constructor(collection: TplCollectionName, fieldName: any, data: T, collectionValues?: IDbCollectionValues<T>);
268
371
  get format(): string;
269
372
  get inputDataSet(): Record<"data-collection" | "data-fieldName" | "data-fieldType" | "data-fieldArgs" | "data-collectionId", string>;
270
373
  get forge(): IDbForge | undefined;
@@ -281,8 +384,8 @@ export declare class IDbCollectionFieldForge<T extends Record<string, any>> {
281
384
  export declare class IDbFormValidate {
282
385
  #private;
283
386
  private collection;
284
- private dbFields;
285
- constructor(collection: TplCollectionName);
387
+ private idbCollections;
388
+ constructor(collection: TplCollectionName, idbCollections?: IDbCollections);
286
389
  validateField(fieldName: keyof TplFields, value: any): {
287
390
  isValid: boolean;
288
391
  error?: string;
@@ -46,12 +46,64 @@ class IDbError extends Error {
46
46
  }
47
47
  }
48
48
  }
49
+ /* Single collection relies on IDbCollections */
50
+ export class IDbCollection {
51
+ collection;
52
+ _dbCollections;
53
+ constructor(collection, dbCollections) {
54
+ this.collection = collection;
55
+ this._dbCollections = dbCollections;
56
+ }
57
+ getCollectionModelTemplate() {
58
+ return this._dbCollections.getCollectionModelTemplate(this.collection);
59
+ }
60
+ getCollectionModelTemplateFks() {
61
+ return this._dbCollections.getCollectionModelTemplateFks(this.collection);
62
+ }
63
+ getIndexName() {
64
+ return this._dbCollections.getIndexName(this.collection);
65
+ }
66
+ collectionValues() {
67
+ return this._dbCollections.getCollectionValues(this.collection);
68
+ }
69
+ collectionFieldValues(data) {
70
+ return this._dbCollections.getCollectionFieldValues(this.collection, data);
71
+ }
72
+ fieldForge(fieldName, data) {
73
+ return this._dbCollections.getCollectionFieldForge(this.collection, fieldName, data);
74
+ }
75
+ getFormValidate() {
76
+ return this._dbCollections.getFormValidate(this.collection);
77
+ }
78
+ fks() {
79
+ return this._dbCollections.fks(this.collection);
80
+ }
81
+ reverseFks() {
82
+ return this._dbCollections.reverseFks(this.collection);
83
+ }
84
+ }
49
85
  /**
50
86
  * Central class for parsing, introspecting, and extracting metadata from the database schema.
51
87
  * Provides methods to access collections, templates, fields, foreign keys, and type information.
52
88
  * Used for dynamic UI generation, validation, and schema-driven logic.
53
89
  */
54
90
  export class IDbCollections {
91
+ /**
92
+ * Stores shared instances of IDbCollectionValues per collection
93
+ */
94
+ _collectionValuesMap = {};
95
+ /**
96
+ * Stores shared instances of IDbCollectionFieldValues per collection+data
97
+ */
98
+ _collectionFieldValuesMap = new Map();
99
+ /**
100
+ * Stores shared instances of IDbCollectionFieldForge per collection, field, and data
101
+ */
102
+ _collectionFieldForgeMap = new Map();
103
+ /**
104
+ * Stores shared instances of IDbFormValidate per collection
105
+ */
106
+ _formValidateMap = new Map();
55
107
  /**
56
108
  * The database model (schema) used for introspection.
57
109
  */
@@ -63,6 +115,9 @@ export class IDbCollections {
63
115
  constructor(model) {
64
116
  this.model = model ?? schemeModel;
65
117
  }
118
+ get(collection) {
119
+ return new IDbCollection(collection, this);
120
+ }
66
121
  /**
67
122
  * Parse all collections in the model and return their fields as IDbForge objects.
68
123
  * @returns An object mapping collection names to their parsed fields.
@@ -83,7 +138,7 @@ export class IDbCollections {
83
138
  const fields = this.getCollectionTemplateFields(collection);
84
139
  if (!fields)
85
140
  return;
86
- let out = {};
141
+ const out = {};
87
142
  Object.keys(fields).forEach((fieldName) => {
88
143
  const fieldType = fields[fieldName];
89
144
  if (fieldType) {
@@ -150,22 +205,29 @@ export class IDbCollections {
150
205
  */
151
206
  getCollection(collection) {
152
207
  return this.#getModel()[String(collection)];
208
+ } /**
209
+ * Get the collection object from the model.
210
+ * @param collection The collection name.
211
+ * @returns The collection object.
212
+ */
213
+ getCollectionModel(collection) {
214
+ return this.#getModel()[String(collection)];
153
215
  }
154
216
  /**
155
217
  * Get the template object for a collection.
156
218
  * @param collection The collection name.
157
219
  * @returns The template object.
158
220
  */
159
- getCollectionTemplate(collection) {
160
- return this.getCollection(collection)['template'];
221
+ getCollectionModelTemplate(collection) {
222
+ return this.getCollectionModel(collection)['template'];
161
223
  }
162
224
  /**
163
225
  * Get the foreign keys (fks) object for a collection.
164
226
  * @param collection The collection name.
165
227
  * @returns The fks object.
166
228
  */
167
- getCollectionTemplateFks(collection) {
168
- return this.getCollection(collection)['template']?.fks;
229
+ getCollectionModelTemplateFks(collection) {
230
+ return this.getCollectionModel(collection)['template']?.fks;
169
231
  }
170
232
  /**
171
233
  * Get the index field name for a collection.
@@ -173,7 +235,51 @@ export class IDbCollections {
173
235
  * @returns The index field name.
174
236
  */
175
237
  getIndexName(collection) {
176
- return this.getCollection(collection)?.template?.index;
238
+ return this.getCollectionModel(collection)?.template?.index;
239
+ }
240
+ /**
241
+ * Returns a shared instance of IDbCollectionValues for a given collection
242
+ */
243
+ getCollectionValues(collection) {
244
+ if (!this._collectionValuesMap[collection]) {
245
+ this._collectionValuesMap[collection] = new IDbCollectionValues(collection, this);
246
+ }
247
+ return this._collectionValuesMap[collection];
248
+ }
249
+ /**
250
+ * Returns a shared instance of IDbCollectionFieldValues for a given collection and data
251
+ * The instance key is based on the collection and the main index of data (or JSON if missing)
252
+ */
253
+ getCollectionFieldValues(collection, data) {
254
+ const indexName = this.getIndexName(collection);
255
+ const indexValue = data?.[indexName];
256
+ const key = `${collection}:${indexValue ?? JSON.stringify(data)}`;
257
+ if (!this._collectionFieldValuesMap.has(key)) {
258
+ this._collectionFieldValuesMap.set(key, new IDbCollectionFieldValues(collection, data, this.getCollectionValues(collection)));
259
+ }
260
+ return this._collectionFieldValuesMap.get(key);
261
+ }
262
+ /**
263
+ * Returns a shared instance of IDbCollectionFieldForge for a given collection, field, and data
264
+ * The instance key is based on collection, field, and the main index of data (or JSON if missing)
265
+ */
266
+ getCollectionFieldForge(collection, fieldName, data) {
267
+ const indexName = this.getIndexName(collection);
268
+ const indexValue = data?.[indexName];
269
+ const key = `${collection}:${String(fieldName)}:${indexValue ?? JSON.stringify(data)}`;
270
+ if (!this._collectionFieldForgeMap.has(key)) {
271
+ this._collectionFieldForgeMap.set(key, new IDbCollectionFieldForge(collection, fieldName, data, this.getCollectionValues(collection)));
272
+ }
273
+ return this._collectionFieldForgeMap.get(key);
274
+ }
275
+ /**
276
+ * Returns a shared instance of IDbFormValidate for a given collection
277
+ */
278
+ getFormValidate(collection) {
279
+ if (!this._formValidateMap.has(collection)) {
280
+ this._formValidateMap.set(collection, new IDbFormValidate(collection, this));
281
+ }
282
+ return this._formValidateMap.get(collection);
177
283
  }
178
284
  /**
179
285
  * Get the fields object for a collection.
@@ -181,7 +287,7 @@ export class IDbCollections {
181
287
  * @returns The fields object.
182
288
  */
183
289
  getCollectionTemplateFields(collection) {
184
- return this.getCollectionTemplate(collection)?.fields;
290
+ return this.getCollectionModelTemplate(collection)?.fields;
185
291
  }
186
292
  /**
187
293
  * Get the presentation string for a collection (used for display).
@@ -189,7 +295,7 @@ export class IDbCollections {
189
295
  * @returns The presentation string.
190
296
  */
191
297
  getTemplatePresentation(collection) {
192
- return this.getCollectionTemplate(collection)?.presentation;
298
+ return this.getCollectionModelTemplate(collection)?.presentation;
193
299
  }
194
300
  #getTemplateFieldRule(collection, fieldName) {
195
301
  return this.getCollectionTemplateFields(collection)?.[String(fieldName)];
@@ -211,7 +317,7 @@ export class IDbCollections {
211
317
  */
212
318
  getFkTemplateFields(string) {
213
319
  const [collection, field] = string.split('.');
214
- return this.getCollection(collection).template?.fields;
320
+ return this.getCollectionModel(collection).template?.fields;
215
321
  }
216
322
  /**
217
323
  * Test if a field rule matches a given type (primitive, array, object, fk).
@@ -384,31 +490,50 @@ export class IDbCollections {
384
490
  }
385
491
  }
386
492
  /**
387
- * Utility class to display and format field values for a collection, based on the schema and provided data.
388
- * Used for dynamic UI rendering, presentation, and extracting metadata for form generation.
389
- * @template T The data type for the collection.
493
+ * IDbCollectionValues
494
+ *
495
+ * This class provides utilities to display, format, and introspect field values for a given collection, using the schema and provided data.
496
+ * It is designed for dynamic UI rendering, presentation logic, and metadata extraction for form generation in schema-driven applications.
497
+ *
498
+ * Main responsibilities:
499
+ * - Holds a reference to the collection name and the schema (IDbCollections).
500
+ * - Provides methods to format field values according to their type (number, text, array, object, etc.).
501
+ * - Supplies presentation logic for displaying records (e.g., presentation string, index value).
502
+ * - Offers input attribute generation for forms (inputDataSet).
503
+ * - Supports iteration over array/object fields for advanced UI layouts.
504
+ * - Enables access to field metadata for validation and rendering.
505
+ *
506
+ * Usage:
507
+ * const values = new IDbCollectionValues('agents');
508
+ * const display = values.presentation(agentData); // formatted display string
509
+ * const index = values.indexValue(agentData); // index field value
510
+ * const formatted = values.format('name', agentData); // formatted field value
511
+ * const attrs = values.getInputDataSet('name', agentData); // input attributes for forms
512
+ *
513
+ * This class is typically used via IDbCollections.getCollectionValues for shared instance management.
514
+ * @template T - The type of the data object for the collection.
390
515
  */
391
516
  export class IDbCollectionValues {
392
517
  /**
393
518
  * The IDbCollections instance used for schema introspection.
394
519
  */
395
- dbCollections;
520
+ idbCollections;
396
521
  /**
397
522
  * The collection name this instance operates on.
398
523
  */
399
- collection;
524
+ collectionName;
400
525
  /**
401
526
  * Create a new IDbCollectionValues instance for a given collection.
402
- * @param collection The collection name.
527
+ * @param collectionName The collection name.
403
528
  */
404
- constructor(collection) {
405
- this.collection = collection;
406
- this.dbCollections = new IDbCollections();
529
+ constructor(collectionName, idbCollections) {
530
+ this.collectionName = collectionName;
531
+ this.idbCollections = idbCollections ?? new IDbCollections();
407
532
  }
408
533
  presentation(data) {
409
534
  try {
410
535
  this.#checkError(!this.#checkAccess(), 'Access denied', 'ACCESS_DENIED');
411
- const presentation = this.dbCollections.getTemplatePresentation(this.collection);
536
+ const presentation = this.idbCollections.getTemplatePresentation(this.collectionName);
412
537
  this.#checkError(!presentation, 'Presentation template not found', 'TEMPLATE_NOT_FOUND');
413
538
  const fields = presentation.split(' ');
414
539
  return fields
@@ -431,7 +556,7 @@ export class IDbCollectionValues {
431
556
  indexValue(data) {
432
557
  try {
433
558
  this.#checkError(!this.#checkAccess(), 'Access denied', 'ACCESS_DENIED');
434
- const indexName = this.dbCollections.getIndexName(this.collection);
559
+ const indexName = this.idbCollections.getIndexName(this.collectionName);
435
560
  this.#checkError(!indexName, 'Index not found for collection', 'INDEX_NOT_FOUND');
436
561
  this.#checkError(!(indexName in data), `Index field ${indexName} not found in data`, 'FIELD_NOT_FOUND');
437
562
  return data[indexName];
@@ -451,7 +576,7 @@ export class IDbCollectionValues {
451
576
  try {
452
577
  this.#checkError(!this.#checkAccess(), 'Access denied', 'ACCESS_DENIED');
453
578
  this.#checkError(!(fieldName in data), `Field ${String(fieldName)} not found in data`, 'FIELD_NOT_FOUND');
454
- const fieldInfo = this.dbCollections.parseCollectionFieldName(this.collection, fieldName);
579
+ const fieldInfo = this.idbCollections.parseCollectionFieldName(this.collectionName, fieldName);
455
580
  this.#checkError(!fieldInfo, `Field ${String(fieldName)} not found in collection`, 'FIELD_NOT_FOUND');
456
581
  switch (fieldInfo?.fieldType) {
457
582
  case 'number':
@@ -479,12 +604,12 @@ export class IDbCollectionValues {
479
604
  * @returns An object with data-* attributes for the field.
480
605
  */
481
606
  getInputDataSet(fieldName, data) {
482
- const fieldInfo = this.dbCollections.parseCollectionFieldName(this.collection, fieldName);
607
+ const fieldInfo = this.idbCollections.parseCollectionFieldName(this.collectionName, fieldName);
483
608
  const fieldType = fieldInfo?.fieldType ?? '';
484
609
  const fieldArgs = fieldInfo?.fieldArgs?.join(' ') ?? '';
485
- const indexName = this.dbCollections.getIndexName(this.collection);
610
+ const indexName = this.idbCollections.getIndexName(this.collectionName);
486
611
  return {
487
- 'data-collection': this.collection,
612
+ 'data-collection': this.collectionName,
488
613
  'data-collectionId': indexName && data?.[indexName] !== undefined ? String(data?.[indexName]) : '',
489
614
  'data-fieldName': String(fieldName),
490
615
  'data-fieldType': fieldType,
@@ -498,7 +623,7 @@ export class IDbCollectionValues {
498
623
  * @returns An array of IDbForge objects.
499
624
  */
500
625
  iterateArrayField(fieldName, data) {
501
- return this.dbCollections.iterateArrayField(this.collection, fieldName, data);
626
+ return this.idbCollections.iterateArrayField(this.collectionName, fieldName, data);
502
627
  }
503
628
  /**
504
629
  * Iterate over an object field and return an array of IDbForge objects for each property.
@@ -507,7 +632,7 @@ export class IDbCollectionValues {
507
632
  * @returns An array of IDbForge objects.
508
633
  */
509
634
  iterateObjectField(fieldName, data) {
510
- return this.dbCollections.iterateObjectField(this.collection, fieldName, data);
635
+ return this.idbCollections.iterateObjectField(this.collectionName, fieldName, data);
511
636
  }
512
637
  /**
513
638
  * Internal: Format a number field for display.
@@ -564,15 +689,15 @@ export class IDbCollectionFieldValues {
564
689
  * @param fieldName The field name to introspect.
565
690
  */
566
691
  getForge(fieldName) {
567
- return this.#collectionValues.dbCollections.parseCollectionFieldName(this.#collection, String(fieldName));
692
+ return this.#collectionValues.idbCollections.parseCollectionFieldName(this.#collection, String(fieldName));
568
693
  }
569
- constructor(collection, data) {
694
+ constructor(collection, data, collectionValues) {
570
695
  this.#collection = collection;
571
- this.#collectionValues = new IDbCollectionValues(collection);
696
+ this.#collectionValues = collectionValues ?? new IDbCollectionValues(collection);
572
697
  this.#data = data;
573
698
  }
574
699
  format(fieldName) {
575
- const fieldInfo = this.#collectionValues.dbCollections.parseCollectionFieldName(this.#collection, fieldName);
700
+ const fieldInfo = this.#collectionValues.idbCollections.parseCollectionFieldName(this.#collection, fieldName);
576
701
  if (fieldInfo?.is === 'array') {
577
702
  return this.iterateArray(String(fieldName), this.#data);
578
703
  }
@@ -595,9 +720,27 @@ export class IDbCollectionFieldValues {
595
720
  return this.#collectionValues.iterateObjectField(fieldName, data);
596
721
  }
597
722
  }
598
- /*
599
- path: D:\boulot\python\wollama\src\lib\db\dbFields.ts
600
- forge values for a collection field and $data
723
+ /**
724
+ * IDbCollectionFieldForge
725
+ *
726
+ * This class provides advanced metadata and formatting for a single field of a collection, given a data object.
727
+ * It is designed for dynamic UI generation, form rendering, and introspection in schema-driven applications.
728
+ *
729
+ * Main responsibilities:
730
+ * - Holds references to the collection name, field name, and the data object for context.
731
+ * - Provides access to the parsed field metadata (IDbForge) for the field, including type, rules, and arguments.
732
+ * - Offers formatting utilities for the field value, adapting to type (number, text, array, object, etc.).
733
+ * - Supplies input attributes and type hints for form generation (e.g., htmlInputType, inputDataSet).
734
+ * - Supports iteration over array/object fields for complex form layouts.
735
+ * - Enables extraction of raw data and field arguments for validation and UI logic.
736
+ *
737
+ * Usage:
738
+ * const forge = new IDbCollectionFieldForge('agents', 'name', agentData);
739
+ * const formatted = forge.format; // formatted value for display
740
+ * const inputType = forge.htmlInputType; // e.g. 'text', 'area', 'email', etc.
741
+ * const meta = forge.forge; // IDbForge metadata for the field
742
+ *
743
+ * This class is typically used via IDbCollections.getCollectionFieldForge for shared instance management.
601
744
  */
602
745
  export class IDbCollectionFieldForge {
603
746
  #collection;
@@ -605,9 +748,9 @@ export class IDbCollectionFieldForge {
605
748
  #fieldName;
606
749
  #data;
607
750
  #forge;
608
- constructor(collection, fieldName, data) {
751
+ constructor(collection, fieldName, data, collectionValues) {
609
752
  this.#collection = collection;
610
- this.#collectionValues = new IDbCollectionValues(collection);
753
+ this.#collectionValues = collectionValues ?? new IDbCollectionValues(collection);
611
754
  this.#fieldName = String(fieldName);
612
755
  this.#data = data;
613
756
  }
@@ -619,7 +762,7 @@ export class IDbCollectionFieldForge {
619
762
  }
620
763
  // renamed from parseCollectionFieldName
621
764
  get forge() {
622
- return this.#collectionValues.dbCollections.parseCollectionFieldName(this.#collection, String(this.#fieldName));
765
+ return this.#collectionValues.idbCollections.parseCollectionFieldName(this.#collection, String(this.#fieldName));
623
766
  }
624
767
  get fieldArgs() {
625
768
  return this.forge?.fieldArgs;
@@ -663,14 +806,14 @@ class IDbValidationError extends Error {
663
806
  }
664
807
  export class IDbFormValidate {
665
808
  collection;
666
- dbFields;
667
- constructor(collection) {
809
+ idbCollections;
810
+ constructor(collection, idbCollections) {
668
811
  this.collection = collection;
669
- this.dbFields = new IDbCollections();
812
+ this.idbCollections = idbCollections ?? new IDbCollections();
670
813
  }
671
814
  validateField(fieldName, value) {
672
815
  try {
673
- const fieldInfo = this.dbFields.parseCollectionFieldName(this.collection, fieldName);
816
+ const fieldInfo = this.idbCollections.parseCollectionFieldName(this.collection, fieldName);
674
817
  if (!fieldInfo) {
675
818
  return { isValid: false, error: `Field ${String(fieldName)} not found in collection` };
676
819
  }
@@ -735,7 +878,7 @@ export class IDbFormValidate {
735
878
  const errors = {};
736
879
  const invalidFields = [];
737
880
  let isValid = true;
738
- const fields = this.dbFields.getCollectionTemplateFields(this.collection);
881
+ const fields = this.idbCollections.getCollectionTemplateFields(this.collection);
739
882
  if (!fields) {
740
883
  return {
741
884
  isValid: false,
@@ -4,6 +4,7 @@
4
4
  import type { TplCollectionName, Where } from '@medyll/idae-idbql';
5
5
  import { Looper } from '@medyll/idae-slotui-svelte';
6
6
 
7
+ import { machine } from '../main/machine.js';
7
8
  type CollectionFksProps = {
8
9
  collection: TplCollectionName;
9
10
  collectionId?: any;
@@ -13,8 +14,9 @@
13
14
 
14
15
  // idbqlState[fkCollection].get(fkId);
15
16
 
16
- const dbFields = new IDbCollections(schemeModel);
17
- const fks = $derived(dbFields.fks(collection));
17
+ const dbFields = machine.collections;
18
+ const collections = new IDbCollections(schemeModel);
19
+ const fks = $derived(collections.fks(collection));
18
20
  </script>
19
21
 
20
22
  <Looper data={Object.entries(fks)}>
@@ -8,12 +8,13 @@
8
8
  type Props,
9
9
  Looper
10
10
  } from '@medyll/idae-slotui-svelte';
11
- import CreateUpdate from './CreateUpdate.svelte';
12
- import { idbqlState } from '../db/dbSchema.js';
13
- import { IDbCollections, IDbCollectionValues } from '../db/dbFields.js';
11
+ import CreateUpdate from './CreateUpdate.svelte';
14
12
  import { hydrate, type Snippet } from 'svelte';
15
13
  import type { Where } from '@medyll/idae-idbql';
16
14
 
15
+ import {machine } from '../main/machine.js';
16
+
17
+
17
18
  interface DataListProps {
18
19
  collection: string;
19
20
  target?: string; // html target
@@ -38,11 +39,12 @@
38
39
  displayMode
39
40
  }: DataListProps = $props();
40
41
 
41
- let test = new IDbCollections();
42
- let fieldValues = new IDbCollectionValues(collection);
43
- let index = test.getIndexName(collection);
42
+ let collections = machine.collections;
43
+ let store = machine.store;
44
+ let fieldValues = machine.collections.get(collection).collectionValues() ;
45
+ let index = collections.get(collection).getIndexName();
44
46
 
45
- let qy = $derived(where ? idbqlState[collection].where(where) : idbqlState[collection].getAll());
47
+ let qy = $derived(where ? store[collection].where(where) : store[collection].getAll());
46
48
 
47
49
  function load(event: CustomEvent, indexV: number | string) {
48
50
  openCrud(event[index]);
@@ -4,11 +4,11 @@
4
4
  -->
5
5
 
6
6
  <script lang="ts" generics="COL = Record<string,any>">
7
- import { IDbCollections as DbFields, IDbFormValidate } from '../db/dbFields';
8
- import { idbql, idbqlState, schemeModel } from '../db/dbSchema';
7
+ import { IDbFormValidate } from '../db/dbFields.js';
9
8
  import type { CreateUpdateProps } from './types';
10
9
  import CollectionReverseFks from './CollectionReverseFks.svelte';
11
10
  import FieldInput from './FieldValue.svelte';
11
+ import {machine} from '../main/machine.js';
12
12
 
13
13
  let {
14
14
  collection,
@@ -22,16 +22,21 @@
22
22
  afterCreate,
23
23
  showFks = false
24
24
  }: CreateUpdateProps = $props();
25
+
26
+
25
27
  let inputForm = `form-${String(collection)}-${mode}`;
26
- let dbFields = new DbFields(schemeModel);
27
- let indexName = dbFields.getIndexName(collection);
28
+
29
+ let collections = machine.collections ;
30
+ let store = machine.store;
31
+ let indexName = collections.getIndexName(collection);
32
+
28
33
  let formFields = showFields
29
34
  ? Object.fromEntries(
30
- Object.entries(dbFields.parseRawCollection(collection) ?? {}).filter(([key]) => showFields.includes(key))
35
+ Object.entries(collections.parseRawCollection(collection) ?? {}).filter(([key]) => showFields.includes(key))
31
36
  )
32
- : (dbFields.parseRawCollection(collection) ?? {});
37
+ : (collections.parseRawCollection(collection) ?? {});
33
38
 
34
- let qy: any = $derived(dataId && indexName ? idbqlState[collection].where({ [indexName]: { eq: dataId } }) : {});
39
+ let qy: any = $derived(dataId && indexName ? store[collection].where({ [indexName]: { eq: dataId } }) : {});
35
40
 
36
41
  let formData = $state<Record<string, any>>({ ...data, ...withData, ...$state.snapshot(qy)[0] });
37
42
 
@@ -86,13 +91,13 @@
86
91
  switch (mode) {
87
92
  case 'create':
88
93
  if (!dataId) {
89
- await idbql[collection].add({ ...datadb, ...withData });
94
+ await store[collection].add({ ...datadb, ...withData });
90
95
  mode = 'show';
91
96
  }
92
97
  break;
93
98
  case 'update':
94
99
  if (dataId) {
95
- await idbqlState[collection].update(dataId, datadb);
100
+ await store[collection].update(dataId, datadb);
96
101
  }
97
102
  break;
98
103
  }
@@ -141,7 +146,8 @@
141
146
  {collection}
142
147
  {fieldName}
143
148
  {mode}
144
- editInPlace={inPlaceEdit === true || (Array.isArray(inPlaceEdit) && inPlaceEdit.includes(fieldName))}
149
+ editInPlace={inPlaceEdit === true ||
150
+ (Array.isArray(inPlaceEdit) && inPlaceEdit.includes(fieldName))}
145
151
  bind:data={formData}
146
152
  {inputForm}
147
153
  />
@@ -1,13 +1,11 @@
1
1
  <!-- Component: CollectionFieldValue.svelte (ancien nom CollectionFieldInput.svelte) -->
2
2
  <script lang="ts" generics="COL = Record<string,any>">
3
- // Importation des types et composants nécessaires
4
- import { IDbCollectionFieldForge, IDbCollectionValues } from '../db/dbFields.js';
5
- import type { TplCollectionName } from '@medyll/idae-idbql';
6
- import { IconButton } from '@medyll/idae-slotui-svelte';
7
- import { getAllContexts, getContext } from 'svelte';
8
-
3
+ // Importation des types et composants nécessaires
4
+ import type { TplCollectionName } from '@medyll/idae-idbql';
5
+ import { getContext } from 'svelte';
6
+ import {machine} from '../main/machine.js';
9
7
  interface FieldValueProps {
10
- collection?: TplCollectionName;
8
+ collection: TplCollectionName;
11
9
  collectionId?: any;
12
10
  fieldName: keyof COL;
13
11
  data?: COL;
@@ -36,11 +34,12 @@
36
34
  data = data ?? ({} as COL);
37
35
 
38
36
  // Initialisation des valeurs de champ de collection
39
- let collectionFieldValues = new IDbCollectionValues(collection);
37
+ const forge = machine.collections.get(collection).fieldForge(String(fieldName), data)
38
+ let collectionFieldValues = machine.collections.get(collection).collectionValues()
40
39
  let inputDataset = collectionFieldValues.getInputDataSet(fieldName, data);
41
40
 
42
41
  // Création d'une instance de forge de champ de collection
43
- const fieldForge = $derived(new IDbCollectionFieldForge(collection, fieldName, data));
42
+ const fieldForge = $derived(forge);
44
43
 
45
44
  // Effet déclenché lorsque collectionId ou editInPlace change
46
45
  $effect(() => {
@@ -1,7 +1,7 @@
1
1
  import type { TplCollectionName } from '@medyll/idae-idbql';
2
2
  declare function $$render<COL = Record<string, any>>(): {
3
3
  props: {
4
- collection?: TplCollectionName;
4
+ collection: TplCollectionName;
5
5
  collectionId?: any;
6
6
  fieldName: keyof COL;
7
7
  data?: COL;
@@ -1,3 +1,29 @@
1
+ /**
2
+ * Example usage:
3
+ *
4
+ * import { Machine } from './machine.js';
5
+ *
6
+ * // Create a new Machine instance with default parameters
7
+ * const machine = new Machine( 'example-db', 1, { collections: {} });
8
+ *
9
+ * // Start the machine (initialize collections and IDBQL connection)
10
+ * machine.start();
11
+ *
12
+ * // Access collections (schema logic)
13
+ * const collections = machine.collections;
14
+ *
15
+ * // Access IDBQL (readonly)
16
+ * const idbql = machine.idbql;
17
+ *
18
+ * // Access IDBQL (stateful)
19
+ * const idbqlState = machine.idbqlState;
20
+ *
21
+ * // Access IndexedDB core
22
+ * const db = machine.indexedb;
23
+ *
24
+ * // Access the IDBQL data model
25
+ * const model = machine.idbqModel;
26
+ */
1
27
  import { IDbCollections } from '../db/dbFields.js';
2
28
  import { createIdbqDb, type IdbqModel } from '@medyll/idae-idbql';
3
29
  /**
@@ -12,7 +38,7 @@ export declare class Machine {
12
38
  /**
13
39
  * IDBQL (stateful collections instance)
14
40
  */
15
- _idbqlState: ReturnType<ReturnType<typeof createIdbqDb>["create"]>["idbqlState"] | undefined;
41
+ _idbqlState: ReturnType<ReturnType<typeof createIdbqDb>["create"]>["idbqlState"];
16
42
  /**
17
43
  * Direct access to IndexedDB (core)
18
44
  */
@@ -24,7 +50,7 @@ export declare class Machine {
24
50
  /**
25
51
  * Centralized access to schema and collection logic
26
52
  */
27
- _collections: IDbCollections | undefined;
53
+ _collections: IDbCollections;
28
54
  /**
29
55
  * Database name
30
56
  */
@@ -39,26 +65,23 @@ export declare class Machine {
39
65
  _model: IdbqModel;
40
66
  /**
41
67
  * Main constructor
42
- * @param dbName Database name (default: 'idae-machine')
43
- * @param version Schema version (default: 1)
44
- * @param model Data model (default: schemeModel)
45
- */
46
- constructor(dbName?: string, version?: number, model?: IdbqModel);
47
- /**
48
- * Start the machine: initialize collections and IDBQL connection.
49
- * @param options Optional overrides: { dbName, version, model }
50
68
  */
51
- start(options?: {
69
+ constructor();
70
+ init(options?: {
52
71
  dbName?: string;
53
72
  version?: number;
54
73
  model?: IdbqModel;
55
74
  }): void;
75
+ /**
76
+ * Start the machine: initialize collections and IDBQL connection.
77
+ */
78
+ start(): void;
56
79
  private createCollections;
57
80
  private createStore;
58
81
  /**
59
82
  * Get the IDbCollections (schema logic) instance
60
83
  */
61
- get collections(): IDbCollections | undefined;
84
+ get collections(): IDbCollections;
62
85
  /**
63
86
  * IDBQL (readonly) instance
64
87
  */
@@ -66,9 +89,10 @@ export declare class Machine {
66
89
  /**
67
90
  * IDBQL (stateful) instance
68
91
  */
69
- get idbqlState(): import("@medyll/idae-idbql").StateCollections<IdbqModel<Record<string, Record<string, any>>>> | undefined;
92
+ get store(): import("@medyll/idae-idbql").StateCollections<IdbqModel<Record<string, Record<string, any>>>>;
70
93
  /**
71
94
  * IndexedDB (core) instance
95
+ * @deprecated
72
96
  */
73
97
  get indexedb(): import("@medyll/idae-idbql").IdbqlIndexedCore<IdbqModel<Record<string, Record<string, any>>>> | undefined;
74
98
  /**
@@ -76,3 +100,4 @@ export declare class Machine {
76
100
  */
77
101
  get idbqModel(): IdbqModel<Record<string, Record<string, any>>> | undefined;
78
102
  }
103
+ export declare const machine: Machine;
@@ -24,7 +24,6 @@
24
24
  * // Access the IDBQL data model
25
25
  * const model = machine.idbqModel;
26
26
  */
27
- import { schemeModel } from '../db/dbSchema.js';
28
27
  import { IDbCollections } from '../db/dbFields.js';
29
28
  import { createIdbqDb } from '@medyll/idae-idbql';
30
29
  /**
@@ -66,23 +65,18 @@ export class Machine {
66
65
  _model;
67
66
  /**
68
67
  * Main constructor
69
- * @param dbName Database name (default: 'idae-machine')
70
- * @param version Schema version (default: 1)
71
- * @param model Data model (default: schemeModel)
72
68
  */
73
- constructor(dbName = 'idae-machine', version = 1, model = schemeModel) {
74
- this._dbName = dbName;
75
- this._version = version;
76
- this._model = model;
69
+ constructor() {
77
70
  }
78
- /**
79
- * Start the machine: initialize collections and IDBQL connection.
80
- * @param options Optional overrides: { dbName, version, model }
81
- */
82
- start(options) {
71
+ init(options) {
83
72
  this._dbName = options?.dbName ?? this._dbName;
84
73
  this._version = options?.version ?? this._version;
85
74
  this._model = options?.model ?? this._model;
75
+ }
76
+ /**
77
+ * Start the machine: initialize collections and IDBQL connection.
78
+ */
79
+ start() {
86
80
  this.createCollections();
87
81
  this.createStore();
88
82
  }
@@ -118,11 +112,12 @@ export class Machine {
118
112
  /**
119
113
  * IDBQL (stateful) instance
120
114
  */
121
- get idbqlState() {
115
+ get store() {
122
116
  return this._idbqlState;
123
117
  }
124
118
  /**
125
119
  * IndexedDB (core) instance
120
+ * @deprecated
126
121
  */
127
122
  get indexedb() {
128
123
  return this._idbDatabase;
@@ -134,3 +129,4 @@ export class Machine {
134
129
  return this._idbqModel;
135
130
  }
136
131
  }
132
+ export const machine = new Machine();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@medyll/idae-machine",
3
- "version": "0.111.0",
3
+ "version": "0.112.0",
4
4
  "scripts": {
5
5
  "dev": "vite dev",
6
6
  "build": "vite build && npm run prepack",
@@ -59,5 +59,8 @@
59
59
  "vite": "^6.2.3",
60
60
  "vitest": "^3.0.9"
61
61
  },
62
- "scope": "@medyll"
63
- }
62
+ "scope": "@medyll",
63
+ "dependencies": {
64
+ "@huggingface/prettier-plugin-vertical-align": "^0.2.3"
65
+ }
66
+ }