@medyll/idae-machine 0.87.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.
Files changed (48) hide show
  1. package/README.md +230 -0
  2. package/dist/db/dataModel.d.ts +23 -0
  3. package/dist/db/dataModel.js +40 -0
  4. package/dist/db/dbFields.d.ts +130 -0
  5. package/dist/db/dbFields.js +606 -0
  6. package/dist/db/dbSchema.d.ts +456 -0
  7. package/dist/db/dbSchema.js +456 -0
  8. package/dist/form/CollectionButton.svelte +26 -0
  9. package/dist/form/CollectionButton.svelte.d.ts +22 -0
  10. package/dist/form/CollectionFieldGuess.svelte +29 -0
  11. package/dist/form/CollectionFieldGuess.svelte.d.ts +11 -0
  12. package/dist/form/CollectionFks.svelte +24 -0
  13. package/dist/form/CollectionFks.svelte.d.ts +9 -0
  14. package/dist/form/CollectionList.svelte +93 -0
  15. package/dist/form/CollectionList.svelte.d.ts +30 -0
  16. package/dist/form/CollectionListMenu.svelte +46 -0
  17. package/dist/form/CollectionListMenu.svelte.d.ts +27 -0
  18. package/dist/form/CollectionReverseFks.svelte +56 -0
  19. package/dist/form/CollectionReverseFks.svelte.d.ts +18 -0
  20. package/dist/form/CreateUpdate.svelte +191 -0
  21. package/dist/form/CreateUpdate.svelte.d.ts +20 -0
  22. package/dist/form/CrudZone.svelte +23 -0
  23. package/dist/form/CrudZone.svelte.d.ts +22 -0
  24. package/dist/form/DataProvider.svelte +20 -0
  25. package/dist/form/DataProvider.svelte.d.ts +9 -0
  26. package/dist/form/FieldInPlace.svelte +49 -0
  27. package/dist/form/FieldInPlace.svelte.d.ts +11 -0
  28. package/dist/form/FieldValue.svelte +213 -0
  29. package/dist/form/FieldValue.svelte.d.ts +28 -0
  30. package/dist/form/types.d.ts +17 -0
  31. package/dist/form/types.js +1 -0
  32. package/dist/fragments/Confirm.svelte +58 -0
  33. package/dist/fragments/Confirm.svelte.d.ts +11 -0
  34. package/dist/fragments/Frame.svelte +19 -0
  35. package/dist/fragments/Frame.svelte.d.ts +32 -0
  36. package/dist/fragments/InfoLine.svelte +21 -0
  37. package/dist/fragments/InfoLine.svelte.d.ts +35 -0
  38. package/dist/fragments/List.svelte +21 -0
  39. package/dist/fragments/List.svelte.d.ts +38 -0
  40. package/dist/fragments/Selector.svelte +26 -0
  41. package/dist/fragments/Selector.svelte.d.ts +38 -0
  42. package/dist/fragments/Skeleton.svelte +21 -0
  43. package/dist/fragments/Skeleton.svelte.d.ts +20 -0
  44. package/dist/index.d.ts +22 -0
  45. package/dist/index.js +23 -0
  46. package/dist/types/appschemeTypes.d.ts +71 -0
  47. package/dist/types/appschemeTypes.js +83 -0
  48. package/package.json +63 -0
package/README.md ADDED
@@ -0,0 +1,230 @@
1
+ # @medyll/idae-machine
2
+
3
+ **Low-code UI framework** for rapid data structure visualization and CRUD operations in Svelte 5. Declare your database schema once, automatically generate rich UI components for displaying, creating, and updating structured data in IndexedDB.
4
+
5
+ ## 🎯 Purpose
6
+
7
+ `idae-machine` bridges the gap between **data modeling** (`@medyll/idae-idbql`) and **rich UI components** (`@medyll/idae-slotui-svelte`). It provides:
8
+ - **Schema-driven UI generation**: Declare your data model, get form components for free
9
+ - **CRUD Zone**: Pre-built "Create-Read-Update-Delete" interface for any collection
10
+ - **Relational support**: Foreign key and reverse foreign key visualization
11
+ - **In-place editing**: Edit records inline without modal dialogs
12
+ - **Field-level validation**: Type-safe field rules (required, readonly, private)
13
+
14
+ ## 📦 Core Architecture
15
+
16
+ ### Layer Stack
17
+
18
+ ```
19
+ UI Components (Svelte 5 Components)
20
+
21
+ Form Management & Validation Logic
22
+
23
+ Database Schema Definition (TypeScript Types)
24
+
25
+ IndexedDB Abstraction (@medyll/idae-idbql)
26
+ ```
27
+
28
+ ### Key Modules
29
+
30
+ | Module | Purpose |
31
+
32
+ ## 🚀 Quick Start
33
+ import { createIdbqDb, type IdbqModel } from '@medyll/idae-idbql';
34
+
35
+ template: {
36
+ index: 'id',
37
+ presentation: 'name',
38
+ fields: {
39
+ id: 'id (readonly)',
40
+ name: 'text (required)',
41
+ code: 'text (required)',
42
+ model: 'text',
43
+ prompt: 'text-long',
44
+ created_at: 'date (private)',
45
+ ia_lock: 'boolean (private)'
46
+ },
47
+ fks: {
48
+ agentPrompt: {
49
+ code: 'agentPrompt',
50
+ multiple: true,
51
+ rules: 'readonly private'
52
+ }
53
+ }
54
+ }
55
+ }
56
+
57
+ export const idbqlState = createIdbqDb(schemeModelDb);
58
+ ```
59
+
60
+ ### 2. Use CRUD Components
61
+
62
+ ```svelte
63
+ <script lang="ts">
64
+ import { CrudZone, CreateUpdate, DataList } from '@medyll/idae-machine';
65
+ </script>
66
+
67
+ <!-- Full CRUD interface -->
68
+ <CrudZone collection="agents" />
69
+
70
+ <!-- Or compose individually -->
71
+ <DataList collection="agents" />
72
+ <CreateUpdate collection="agents" mode="create" />
73
+ ```
74
+
75
+ ## 📋 Component Guide
76
+
77
+ ### `<CrudZone>`
78
+ Unified CRUD interface with sidebar list and detail editing.
79
+ ```svelte
80
+ <CrudZone collection="agents" style="height: 600px; min-width: 750px" />
81
+ ```
82
+
83
+ ### `<DataList>`
84
+ Displays collection records as grid with click-to-edit.
85
+ ```svelte
86
+ <DataList
87
+ collection="agents"
88
+ displayMode="grid"
89
+ where={{ active: { $eq: true } }}
90
+ onclick={(data, idx) => console.log(data)}
91
+ />
92
+ ```
93
+
94
+ ### `<CreateUpdate>`
95
+ Form for creating/updating/viewing records.
96
+ ```svelte
97
+ <CreateUpdate
98
+ collection="agents"
99
+ mode="show"
100
+ dataId={1}
101
+ showFields={['name', 'code', 'model']}
102
+ inPlaceEdit={true}
103
+ showFks={true}
104
+ />
105
+ ```
106
+
107
+ ### `<FieldValue>`
108
+ Renders a single field with intelligent type detection.
109
+ ```svelte
110
+ <FieldValue
111
+ collection="agents"
112
+ fieldName="name"
113
+ data={formData}
114
+ mode="edit"
115
+ editInPlace={true}
116
+ />
117
+ ```
118
+
119
+ ### Relational Components
120
+ ```svelte
121
+ <!-- Foreign Keys (refs TO other collections) -->
122
+ <CollectionFks collection="agents" />
123
+
124
+ <!-- Reverse Foreign Keys (records pointing TO this one) -->
125
+ <CollectionReverseFks collection="agents">
126
+ {#snippet children({ collection, template })}
127
+ <div>{collection} references this agent</div>
128
+ {/snippet}
129
+ </CollectionReverseFks>
130
+ ```
131
+
132
+ ## 🔧 Schema Definition (dbFields.ts)
133
+
134
+ Field types are declared using string-based DSL:
135
+
136
+ ```typescript
137
+ fields: {
138
+ // Primitives
139
+ id: 'id (readonly)',
140
+ name: 'text (required)',
141
+ age: 'number',
142
+ active: 'boolean',
143
+ email: 'email',
144
+ created: 'date',
145
+
146
+ // Text variants
147
+ bio: 'text-long',
148
+ note: 'text-area',
149
+
150
+ // Relations
151
+ categoryId: 'fk-category.id (required)',
152
+
153
+ // Collections
154
+ tagIds: 'array-of-number',
155
+
156
+ // Modifiers
157
+ password: 'password (private)',
158
+ system_field: 'text (readonly private)'
159
+ }
160
+ ```
161
+
162
+ ## 📝 Development Status
163
+
164
+ ⚠️ **Early Development Phase**
165
+
166
+ This package contains foundational code that is:
167
+ - **Partially validated**: Core schema & field system works; form validation in progress
168
+ - **Under active refinement**: API may change as patterns solidify
169
+ - **Proof of concept**: Not recommended for production until v1.0 release
170
+
171
+ ### Current Focus Areas
172
+ - ✅ Schema declaration & type safety
173
+ - ✅ Database integration with idae-idbql
174
+ - ✅ Component exports & library structure
175
+ - 🔄 Form validation (in progress)
176
+ - 🔄 Field rendering pipeline (needs refinement)
177
+ - ⏳ End-to-end CRUD workflows
178
+ - ⏳ Comprehensive test coverage
179
+
180
+ ## 🔗 Dependencies
181
+
182
+ - **@medyll/idae-idbql**: IndexedDB abstraction with schema support
183
+ - **@medyll/idae-slotui-svelte**: UI component library (Button, MenuList, Looper, etc.)
184
+ - **svelte**: ^5.0.0 (uses Svelte 5 runes)
185
+ ### Build
186
+ ```bash
187
+ ### Development Server
188
+ ```bash
189
+ npm run dev # Start dev server on localhost
190
+ npm run dev -- --open # Auto-open in browser
191
+ ```
192
+
193
+ ### Quality Assurance
194
+ ```bash
195
+ npm run check # Svelte type checking
196
+ npm run lint # ESLint + Prettier check
197
+ npm run format # Auto-format code
198
+ npm run test:unit # Run Vitest unit tests
199
+ npm run test # Single-run test mode
200
+ ```
201
+
202
+ ## 📚 Code Structure
203
+
204
+ ```
205
+ src/lib/
206
+ ├── db/ # Schema & field layers
207
+ │ ├── dbSchema.ts # Collection templates
208
+ │ ├── dbFields.ts # Field rules & validation
209
+ │ └── dataModel.ts # TypeScript types
210
+ │ ├── CollectionFks.svelte # Forward relations
211
+ │ ├── CollectionReverseFks.svelte # Back-references
212
+ │ └── ...
213
+ └── index.ts # Main exports
214
+ ```
215
+
216
+ ## 🎓 Example Projects
217
+
218
+ See `src/routes/` for a working showcase of all components in action.
219
+
220
+ ## 📄 License
221
+
222
+ MIT - See LICENSE file
223
+
224
+ ---
225
+
226
+ **Next Steps for Contributors:**
227
+ 1. Stabilize form validation pipeline
228
+ 2. Add comprehensive test suite
229
+ 3. Document TypeScript schema inference
230
+ 4. Create migration guides from legacy code in `src/_old/`
@@ -0,0 +1,23 @@
1
+ export type DbDataModel<T = Record<string, CollectionDbModel>> = {
2
+ readonly [K in keyof T]: CollectionDbModel<T[K]>;
3
+ };
4
+ export interface CollectionDbModel<T = Record<string, any>> {
5
+ keyPath: string | any;
6
+ ts: any;
7
+ model: any;
8
+ template?: {
9
+ index: string;
10
+ presentation: any;
11
+ fields?: {};
12
+ fks?: {
13
+ code: string;
14
+ multiple: boolean;
15
+ rules: string;
16
+ };
17
+ };
18
+ }
19
+ export type DbDataModelTs<T extends Record<string, {
20
+ ts: any;
21
+ }> = DbDataModel> = {
22
+ [K in keyof T]: T[K]['ts'];
23
+ };
@@ -0,0 +1,40 @@
1
+ const monModel = {
2
+ agent: {
3
+ keyPath: '++id, promptId, created_at',
4
+ ts: {},
5
+ model: {},
6
+ template: {
7
+ index: 'id',
8
+ presentation: 'name model',
9
+ fields: {
10
+ id: 'id (readonly)',
11
+ name: 'text (private)',
12
+ code: 'text',
13
+ model: 'text',
14
+ prompt: 'text-long',
15
+ created_at: 'date (private)',
16
+ ia_lock: 'boolean (private)',
17
+ agentPromptId: 'fk-agentPrompt.id (required)'
18
+ }
19
+ }
20
+ },
21
+ agentPrompt: {
22
+ keyPath: '++id, created_at',
23
+ ts: {},
24
+ model: {},
25
+ template: {
26
+ index: 'id',
27
+ presentation: 'name',
28
+ fields: {
29
+ id: 'id (readonly)',
30
+ created_at: 'date (private)',
31
+ value: 'text-long (required)',
32
+ name: 'text (required)',
33
+ code: 'text (required)',
34
+ ia_lock: 'boolean (private)'
35
+ }
36
+ }
37
+ }
38
+ };
39
+ export {};
40
+ //
@@ -0,0 +1,130 @@
1
+ import type { CollectionModel, IdbqModel, TplCollectionName, Tpl, TplFields } from '@medyll/idae-idbql';
2
+ export declare enum enumPrimitive {
3
+ id = "id",
4
+ any = "any",
5
+ date = "date",
6
+ datetime = "datetime",
7
+ time = "time",
8
+ text = "text",
9
+ number = "number",
10
+ boolean = "boolean",
11
+ url = "url",
12
+ email = "email",
13
+ phone = "phone",
14
+ password = "password"
15
+ }
16
+ export declare enum TplProperties {
17
+ 'private' = "private",
18
+ 'readonly' = "readonly",
19
+ 'required' = "required"
20
+ }
21
+ type CombineElements<T extends string, U extends string = T> = T extends any ? T | `${T} ${CombineElements<Exclude<U, T>>}` : never;
22
+ type CombinedArgs = CombineElements<TplProperties>;
23
+ type IdbObjectify<T extends string = 'number'> = `array-of-${T}` | `object-${T}`;
24
+ export type IdDbPrimitive<T = {}> = keyof typeof enumPrimitive | `text-${'tiny' | 'short' | 'medium' | 'long' | 'area'}` | `${string}.${string}` | `fk-${string}.${string}`;
25
+ export type IDbObjectPrimitive = IdbObjectify<IdDbPrimitive>;
26
+ export type IDbFk = `fk-${string}.${string}`;
27
+ export type IDbFkObject = IdbObjectify<IDbFk>;
28
+ export type IDbTypes = IdDbPrimitive | IDbObjectPrimitive | IDbFk | IDbFkObject;
29
+ export type IDBArgumentsTypes = `${IDbTypes}(${CombinedArgs})`;
30
+ export type IDbFieldRules = IDBArgumentsTypes | IDbTypes;
31
+ export type IDbFieldType = IDBArgumentsTypes | IDbTypes;
32
+ type IDbForgeArgs = keyof typeof TplProperties;
33
+ export type IDbForge = {
34
+ collection?: TplCollectionName;
35
+ fieldName?: keyof TplFields;
36
+ fieldType?: IDbFieldType;
37
+ fieldRule?: IDbFieldRules;
38
+ fieldArgs?: IDbForgeArgs | undefined;
39
+ is: any;
40
+ };
41
+ export declare class IDbCollections {
42
+ #private;
43
+ model: IdbqModel;
44
+ constructor(model?: IdbqModel);
45
+ parseAllCollections(): Record<string, Record<string, IDbForge | undefined> | undefined>;
46
+ parseRawCollection(collection: TplCollectionName): Record<string, IDbForge | undefined> | undefined;
47
+ parseCollectionFieldName(collection: TplCollectionName, fieldName: keyof TplFields): IDbForge | undefined;
48
+ parsFieldRule(fieldRule: IDbFieldRules): Partial<IDbForge> | undefined;
49
+ private forge;
50
+ getCollection(collection: TplCollectionName): CollectionModel;
51
+ getCollectionTemplate(collection: TplCollectionName): Tpl;
52
+ getCollectionTemplateFks(collection: TplCollectionName): Tpl["fks"];
53
+ getIndexName(collection: string): string;
54
+ getCollectionTemplateFields(collection: TplCollectionName): TplFields;
55
+ getTemplatePresentation(collection: TplCollectionName): string;
56
+ getFkFieldType(string: `${string}.${string}`): IDbFieldRules | undefined;
57
+ getFkTemplateFields(string: `${string}.${string}`): {
58
+ [x: string]: import("@medyll/idae-idbql").TplFieldRules;
59
+ };
60
+ private testIs;
61
+ is(what: 'array' | 'object' | 'fk' | 'primitive', fieldRule: IDbFieldRules): Partial<IDbForge>;
62
+ indexValue(collection: TplCollectionName, data: Record<string, any>): any;
63
+ extract(type: 'array' | 'object' | 'fk' | 'primitive', fieldRule: IDbFieldRules): Partial<IDbForge>;
64
+ fks(collection: string): {
65
+ [collection: string]: Tpl;
66
+ };
67
+ reverseFks(targetCollection: TplCollectionName): Record<string, any>;
68
+ iterateArrayField(collection: TplCollectionName, fieldName: keyof TplFields, data: any[]): IDbForge[];
69
+ iterateObjectField(collection: TplCollectionName, fieldName: keyof TplFields, data: Record<string, any>): IDbForge[];
70
+ }
71
+ export declare class IDbCollectionValues<T extends Record<string, any>> {
72
+ #private;
73
+ dbCollections: IDbCollections;
74
+ private collection;
75
+ constructor(collection: TplCollectionName);
76
+ presentation(data: Record<string, any>): string;
77
+ indexValue(data: Record<string, any>): any | null;
78
+ format(fieldName: keyof T, data: T): string;
79
+ getInputDataSet(fieldName: string, data: T): Record<`data-${'collection' | 'collectionId' | 'fieldName' | 'fieldType' | 'fieldArgs'}`, string>;
80
+ iterateArrayField(fieldName: keyof TplFields, data: any[]): IDbForge[];
81
+ iterateObjectField(fieldName: keyof TplFields, data: Record<string, any>): IDbForge[];
82
+ }
83
+ export declare class IDbCollectionFieldValues<T extends Record<string, any>> {
84
+ #private;
85
+ constructor(collection: TplCollectionName, data: T);
86
+ format(fieldName: keyof T): string | string[];
87
+ getInputDataSet(fieldName: keyof T): Record<"data-collection" | "data-fieldName" | "data-fieldType" | "data-fieldArgs" | "data-collectionId", string>;
88
+ getForge(fieldName: keyof T): IDbForge | undefined;
89
+ iterateArray(fieldName: string, data: any[]): IDbForge[];
90
+ iterateObject(fieldName: string, data: Record<string, any>): IDbForge[];
91
+ }
92
+ export declare class IDbCollectionFieldForge<T extends Record<string, any>> {
93
+ #private;
94
+ constructor(collection: TplCollectionName, fieldName: any, data: T);
95
+ get format(): string;
96
+ get inputDataSet(): Record<"data-collection" | "data-fieldName" | "data-fieldType" | "data-fieldArgs" | "data-collectionId", string>;
97
+ get forge(): IDbForge | undefined;
98
+ get fieldArgs(): IDbForgeArgs | undefined;
99
+ get fieldType(): IDbFieldType | undefined;
100
+ /**
101
+ * will return text.inputBase for ['url', 'email', 'number', 'date', 'time', 'datetime', 'phone', 'password']
102
+ */
103
+ get htmlInputType(): string | 'text' | 'area';
104
+ get rawData(): T;
105
+ iterateArray(fieldName: string, data: any[]): IDbForge[];
106
+ iterateObject(fieldName: string, data: Record<string, any>): IDbForge[];
107
+ }
108
+ export declare class IDbFormValidate {
109
+ #private;
110
+ private collection;
111
+ private dbFields;
112
+ constructor(collection: TplCollectionName);
113
+ validateField(fieldName: keyof TplFields, value: any): {
114
+ isValid: boolean;
115
+ error?: string;
116
+ };
117
+ validateFieldValue(fieldName: keyof TplFields, value: any): boolean;
118
+ validateForm(formData: Record<string, any>, options?: {
119
+ ignoreFields?: string[] | undefined;
120
+ }): {
121
+ isValid: boolean;
122
+ errors: Record<string, string>;
123
+ invalidFields: string[];
124
+ };
125
+ private validateEmail;
126
+ private validateUrl;
127
+ private validatePhone;
128
+ private validateDateTime;
129
+ }
130
+ export {};