@medyll/idae-idbql 0.178.0 → 0.185.2
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/LICENSE +21 -21
- package/README.md +204 -204
- package/cli.js +46 -0
- package/dist/idbqlCore/types.d.ts +4 -115
- package/dist/idbqlCore/types.js +0 -10
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/state/idbstate.svelte.d.ts +4 -5
- package/dist/state/idbstate.svelte.js +7 -8
- package/package.json +17 -4
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2024 medyll
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 medyll
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,205 +1,205 @@
|
|
|
1
|
-
# @medyll/idae-idbql
|
|
2
|
-
|
|
3
|
-
A powerful and flexible IndexedDB query library for TypeScript and JavaScript applications.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- MongoDB-like query interface for IndexedDB
|
|
8
|
-
- Strong TypeScript support with full type inference
|
|
9
|
-
- Reactive state management for real-time UI updates
|
|
10
|
-
- Support for complex CRUD operations and advanced querying
|
|
11
|
-
- Flexible data modeling with automatic schema creation
|
|
12
|
-
- Built-in indexing and optimization features
|
|
13
|
-
- Easy integration with front-end frameworks, especially Svelte
|
|
14
|
-
- Robust error handling and logging
|
|
15
|
-
- Versioning and database migration support
|
|
16
|
-
- Support for svelte 5 state
|
|
17
|
-
|
|
18
|
-
## Installation
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
npm install @medyll/idae-idbql
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
## Quick Start
|
|
25
|
-
|
|
26
|
-
```typescript
|
|
27
|
-
import { createIdbqDb } from '@medyll/idae-idbql';
|
|
28
|
-
|
|
29
|
-
// Define your data model
|
|
30
|
-
const exampleModel = {
|
|
31
|
-
messages: {
|
|
32
|
-
keyPath: "++id, chatId, created_at",
|
|
33
|
-
ts: {} as ChatMessage, // this will provide autocompletion
|
|
34
|
-
},
|
|
35
|
-
chat: {
|
|
36
|
-
keyPath: "&chatId, created_at, dateLastMessage",
|
|
37
|
-
ts: {} as Chat,
|
|
38
|
-
template: {
|
|
39
|
-
index: string;
|
|
40
|
-
presentation: CombineElements<keyof CollectionModel<T>['ts']>;
|
|
41
|
-
fields: {
|
|
42
|
-
[K in keyof T]: TplFieldRules;
|
|
43
|
-
field1: 'array-of-string';
|
|
44
|
-
field2: 'string (readonly private)';
|
|
45
|
-
field3: 'text-short'
|
|
46
|
-
field4: 'fks-messages.is'
|
|
47
|
-
};
|
|
48
|
-
fks: {
|
|
49
|
-
[K in TplCollectionName]?: {
|
|
50
|
-
code: K;
|
|
51
|
-
multiple: boolean;
|
|
52
|
-
rules: CombinedArgs;
|
|
53
|
-
};
|
|
54
|
-
};
|
|
55
|
-
};
|
|
56
|
-
},
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
// Create a database instance
|
|
60
|
-
const idbqStore = createIdbqDb(exampleModel, 1);
|
|
61
|
-
const { idbql, idbqlState, idbDatabase, idbqModel } = idbqStore.create("myDatabase");
|
|
62
|
-
|
|
63
|
-
// Perform database operations
|
|
64
|
-
async function fetchMessages() {
|
|
65
|
-
const messages = await idbql.messages.where({ chatId: "123" }).toArray();
|
|
66
|
-
console.log(messages);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
fetchMessages();
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
## API Reference
|
|
73
|
-
|
|
74
|
-
### createIdbqDb(model, version)
|
|
75
|
-
|
|
76
|
-
Creates an IndexedDB database instance with the specified model and version.
|
|
77
|
-
|
|
78
|
-
### idbql
|
|
79
|
-
|
|
80
|
-
The main interface for database operations. Provides methods for each collection defined in your model.
|
|
81
|
-
|
|
82
|
-
### idbqlState
|
|
83
|
-
|
|
84
|
-
A reactive state object that reflects the current state of your database.
|
|
85
|
-
|
|
86
|
-
### idbDatabase
|
|
87
|
-
|
|
88
|
-
Provides low-level access to the IndexedDB instance.
|
|
89
|
-
|
|
90
|
-
### idbqModel
|
|
91
|
-
|
|
92
|
-
Contains the database model definition.
|
|
93
|
-
|
|
94
|
-
## Query Operations
|
|
95
|
-
|
|
96
|
-
```typescript
|
|
97
|
-
// Add a new item
|
|
98
|
-
await idbql.messages.add({ chatId: "123", content: "Hello" });
|
|
99
|
-
|
|
100
|
-
// Update an item
|
|
101
|
-
await idbql.messages.put({ id: 1, content: "Updated message" });
|
|
102
|
-
|
|
103
|
-
// Delete an item
|
|
104
|
-
await idbql.messages.delete(1);
|
|
105
|
-
|
|
106
|
-
// Query items
|
|
107
|
-
const recentMessages = await idbql.messages
|
|
108
|
-
.where({ created_at: { gt: new Date(Date.now() - 86400000) } })
|
|
109
|
-
.toArray();
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
## Transactions
|
|
113
|
-
|
|
114
|
-
idbql supports complex transactions across multiple object stores:
|
|
115
|
-
|
|
116
|
-
```typescript
|
|
117
|
-
const result = await idbql.transaction(
|
|
118
|
-
["users", "posts"],
|
|
119
|
-
"readwrite",
|
|
120
|
-
async (tx) => {
|
|
121
|
-
const userStore = tx.objectStore("users");
|
|
122
|
-
const postStore = tx.objectStore("posts");
|
|
123
|
-
|
|
124
|
-
const userId = await userStore.add({ name: "Alice", email: "alice@example.com" });
|
|
125
|
-
const postId = await postStore.add({ userId, title: "Alice's First Post", content: "Hello, World!" });
|
|
126
|
-
|
|
127
|
-
return { userId, postId };
|
|
128
|
-
}
|
|
129
|
-
);
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
## Svelte 5 Reactivity: Usage & Best Practices
|
|
134
|
-
|
|
135
|
-
`idbqlState` expose un state réactif Svelte 5 ($state) : toute modification (add, update, delete…) se propage automatiquement à toutes les requêtes (`where`, `groupby`, `sort`, etc.) utilisées dans un `$derived` ou `$effect`.
|
|
136
|
-
|
|
137
|
-
### Exemple d'usage réactif dans un composant Svelte 5
|
|
138
|
-
|
|
139
|
-
```svelte
|
|
140
|
-
<script lang="ts">
|
|
141
|
-
// Importez idbqlState depuis votre store
|
|
142
|
-
import { idbqlState } from './store';
|
|
143
|
-
|
|
144
|
-
// Utilisez $derived pour obtenir une liste réactive
|
|
145
|
-
// Toute modification de la base (ajout, suppression, update) mettra à jour $activeUsers automatiquement
|
|
146
|
-
const activeUsers = $derived(() => idbqlState.users.where({ isActive: true }));
|
|
147
|
-
</script>
|
|
148
|
-
|
|
149
|
-
<h2>Utilisateurs actifs</h2>
|
|
150
|
-
{#each $activeUsers as user}
|
|
151
|
-
<p>{user.name}</p>
|
|
152
|
-
{/each}
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
### Notes importantes
|
|
156
|
-
- Les méthodes `where`, `groupby`, `sort`, etc. sont synchrones : elles opèrent toujours sur le snapshot courant du state.
|
|
157
|
-
- Pour bénéficier de la réactivité, utilisez-les dans un `$derived` ou `$effect` Svelte 5.
|
|
158
|
-
|
|
159
|
-
## Versioning and Migrations
|
|
160
|
-
|
|
161
|
-
```typescript
|
|
162
|
-
const idbqStore = createIdbqDb(myModel, 2);
|
|
163
|
-
const { idbDatabase } = idbqStore.create("myDb", {
|
|
164
|
-
upgrade(oldVersion, newVersion, transaction) {
|
|
165
|
-
if (oldVersion < 2) {
|
|
166
|
-
const userStore = transaction.objectStore("users");
|
|
167
|
-
userStore.createIndex("emailIndex", "email", { unique: true });
|
|
168
|
-
}
|
|
169
|
-
},
|
|
170
|
-
});
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
## Error Handling
|
|
174
|
-
|
|
175
|
-
```typescript
|
|
176
|
-
try {
|
|
177
|
-
await idbql.users.add({ username: "existing_user" });
|
|
178
|
-
} catch (error) {
|
|
179
|
-
if (error instanceof UniqueConstraintError) {
|
|
180
|
-
console.error("Username already exists");
|
|
181
|
-
} else {
|
|
182
|
-
console.error("An unexpected error occurred", error);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
## Performance Tips
|
|
188
|
-
|
|
189
|
-
- Use appropriate indexes
|
|
190
|
-
- Limit result sets with `.limit(n)`
|
|
191
|
-
- Use `.count()` instead of `.toArray().length`
|
|
192
|
-
- Optimize queries to use indexes effectively
|
|
193
|
-
|
|
194
|
-
## Contributing
|
|
195
|
-
|
|
196
|
-
Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.
|
|
197
|
-
|
|
198
|
-
## License
|
|
199
|
-
|
|
200
|
-
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
|
|
201
|
-
|
|
202
|
-
## Support
|
|
203
|
-
|
|
204
|
-
If you encounter any issues or have questions, please file an issue on the GitHub repository.
|
|
1
|
+
# @medyll/idae-idbql
|
|
2
|
+
|
|
3
|
+
A powerful and flexible IndexedDB query library for TypeScript and JavaScript applications.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- MongoDB-like query interface for IndexedDB
|
|
8
|
+
- Strong TypeScript support with full type inference
|
|
9
|
+
- Reactive state management for real-time UI updates
|
|
10
|
+
- Support for complex CRUD operations and advanced querying
|
|
11
|
+
- Flexible data modeling with automatic schema creation
|
|
12
|
+
- Built-in indexing and optimization features
|
|
13
|
+
- Easy integration with front-end frameworks, especially Svelte
|
|
14
|
+
- Robust error handling and logging
|
|
15
|
+
- Versioning and database migration support
|
|
16
|
+
- Support for svelte 5 state
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install @medyll/idae-idbql
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Quick Start
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { createIdbqDb } from '@medyll/idae-idbql';
|
|
28
|
+
|
|
29
|
+
// Define your data model
|
|
30
|
+
const exampleModel = {
|
|
31
|
+
messages: {
|
|
32
|
+
keyPath: "++id, chatId, created_at",
|
|
33
|
+
ts: {} as ChatMessage, // this will provide autocompletion
|
|
34
|
+
},
|
|
35
|
+
chat: {
|
|
36
|
+
keyPath: "&chatId, created_at, dateLastMessage",
|
|
37
|
+
ts: {} as Chat,
|
|
38
|
+
template: {
|
|
39
|
+
index: string;
|
|
40
|
+
presentation: CombineElements<keyof CollectionModel<T>['ts']>;
|
|
41
|
+
fields: {
|
|
42
|
+
[K in keyof T]: TplFieldRules;
|
|
43
|
+
field1: 'array-of-string';
|
|
44
|
+
field2: 'string (readonly private)';
|
|
45
|
+
field3: 'text-short'
|
|
46
|
+
field4: 'fks-messages.is'
|
|
47
|
+
};
|
|
48
|
+
fks: {
|
|
49
|
+
[K in TplCollectionName]?: {
|
|
50
|
+
code: K;
|
|
51
|
+
multiple: boolean;
|
|
52
|
+
rules: CombinedArgs;
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// Create a database instance
|
|
60
|
+
const idbqStore = createIdbqDb(exampleModel, 1);
|
|
61
|
+
const { idbql, idbqlState, idbDatabase, idbqModel } = idbqStore.create("myDatabase");
|
|
62
|
+
|
|
63
|
+
// Perform database operations
|
|
64
|
+
async function fetchMessages() {
|
|
65
|
+
const messages = await idbql.messages.where({ chatId: "123" }).toArray();
|
|
66
|
+
console.log(messages);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
fetchMessages();
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## API Reference
|
|
73
|
+
|
|
74
|
+
### createIdbqDb(model, version)
|
|
75
|
+
|
|
76
|
+
Creates an IndexedDB database instance with the specified model and version.
|
|
77
|
+
|
|
78
|
+
### idbql
|
|
79
|
+
|
|
80
|
+
The main interface for database operations. Provides methods for each collection defined in your model.
|
|
81
|
+
|
|
82
|
+
### idbqlState
|
|
83
|
+
|
|
84
|
+
A reactive state object that reflects the current state of your database.
|
|
85
|
+
|
|
86
|
+
### idbDatabase
|
|
87
|
+
|
|
88
|
+
Provides low-level access to the IndexedDB instance.
|
|
89
|
+
|
|
90
|
+
### idbqModel
|
|
91
|
+
|
|
92
|
+
Contains the database model definition.
|
|
93
|
+
|
|
94
|
+
## Query Operations
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
// Add a new item
|
|
98
|
+
await idbql.messages.add({ chatId: "123", content: "Hello" });
|
|
99
|
+
|
|
100
|
+
// Update an item
|
|
101
|
+
await idbql.messages.put({ id: 1, content: "Updated message" });
|
|
102
|
+
|
|
103
|
+
// Delete an item
|
|
104
|
+
await idbql.messages.delete(1);
|
|
105
|
+
|
|
106
|
+
// Query items
|
|
107
|
+
const recentMessages = await idbql.messages
|
|
108
|
+
.where({ created_at: { gt: new Date(Date.now() - 86400000) } })
|
|
109
|
+
.toArray();
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Transactions
|
|
113
|
+
|
|
114
|
+
idbql supports complex transactions across multiple object stores:
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
const result = await idbql.transaction(
|
|
118
|
+
["users", "posts"],
|
|
119
|
+
"readwrite",
|
|
120
|
+
async (tx) => {
|
|
121
|
+
const userStore = tx.objectStore("users");
|
|
122
|
+
const postStore = tx.objectStore("posts");
|
|
123
|
+
|
|
124
|
+
const userId = await userStore.add({ name: "Alice", email: "alice@example.com" });
|
|
125
|
+
const postId = await postStore.add({ userId, title: "Alice's First Post", content: "Hello, World!" });
|
|
126
|
+
|
|
127
|
+
return { userId, postId };
|
|
128
|
+
}
|
|
129
|
+
);
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
## Svelte 5 Reactivity: Usage & Best Practices
|
|
134
|
+
|
|
135
|
+
`idbqlState` expose un state réactif Svelte 5 ($state) : toute modification (add, update, delete…) se propage automatiquement à toutes les requêtes (`where`, `groupby`, `sort`, etc.) utilisées dans un `$derived` ou `$effect`.
|
|
136
|
+
|
|
137
|
+
### Exemple d'usage réactif dans un composant Svelte 5
|
|
138
|
+
|
|
139
|
+
```svelte
|
|
140
|
+
<script lang="ts">
|
|
141
|
+
// Importez idbqlState depuis votre store
|
|
142
|
+
import { idbqlState } from './store';
|
|
143
|
+
|
|
144
|
+
// Utilisez $derived pour obtenir une liste réactive
|
|
145
|
+
// Toute modification de la base (ajout, suppression, update) mettra à jour $activeUsers automatiquement
|
|
146
|
+
const activeUsers = $derived(() => idbqlState.users.where({ isActive: true }));
|
|
147
|
+
</script>
|
|
148
|
+
|
|
149
|
+
<h2>Utilisateurs actifs</h2>
|
|
150
|
+
{#each $activeUsers as user}
|
|
151
|
+
<p>{user.name}</p>
|
|
152
|
+
{/each}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Notes importantes
|
|
156
|
+
- Les méthodes `where`, `groupby`, `sort`, etc. sont synchrones : elles opèrent toujours sur le snapshot courant du state.
|
|
157
|
+
- Pour bénéficier de la réactivité, utilisez-les dans un `$derived` ou `$effect` Svelte 5.
|
|
158
|
+
|
|
159
|
+
## Versioning and Migrations
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
const idbqStore = createIdbqDb(myModel, 2);
|
|
163
|
+
const { idbDatabase } = idbqStore.create("myDb", {
|
|
164
|
+
upgrade(oldVersion, newVersion, transaction) {
|
|
165
|
+
if (oldVersion < 2) {
|
|
166
|
+
const userStore = transaction.objectStore("users");
|
|
167
|
+
userStore.createIndex("emailIndex", "email", { unique: true });
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
});
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Error Handling
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
try {
|
|
177
|
+
await idbql.users.add({ username: "existing_user" });
|
|
178
|
+
} catch (error) {
|
|
179
|
+
if (error instanceof UniqueConstraintError) {
|
|
180
|
+
console.error("Username already exists");
|
|
181
|
+
} else {
|
|
182
|
+
console.error("An unexpected error occurred", error);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Performance Tips
|
|
188
|
+
|
|
189
|
+
- Use appropriate indexes
|
|
190
|
+
- Limit result sets with `.limit(n)`
|
|
191
|
+
- Use `.count()` instead of `.toArray().length`
|
|
192
|
+
- Optimize queries to use indexes effectively
|
|
193
|
+
|
|
194
|
+
## Contributing
|
|
195
|
+
|
|
196
|
+
Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.
|
|
197
|
+
|
|
198
|
+
## License
|
|
199
|
+
|
|
200
|
+
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
|
|
201
|
+
|
|
202
|
+
## Support
|
|
203
|
+
|
|
204
|
+
If you encounter any issues or have questions, please file an issue on the GitHub repository.
|
|
205
205
|
|
package/cli.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
const pkgJson = require(path.join(__dirname, 'package.json'));
|
|
8
|
+
const packageName = pkgJson.name.replace(/^@[^/]+\//, '');
|
|
9
|
+
const cmd = process.argv[2];
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
if (cmd === 'get-readme') {
|
|
13
|
+
const readmePath = path.join(__dirname, 'README.md');
|
|
14
|
+
if (fs.existsSync(readmePath)) {
|
|
15
|
+
const content = fs.readFileSync(readmePath, 'utf8');
|
|
16
|
+
console.log(content);
|
|
17
|
+
} else {
|
|
18
|
+
console.error('README.md not found in this package.');
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
} else if (cmd === 'install-skill') {
|
|
22
|
+
const readline = require('readline');
|
|
23
|
+
const rl = readline.createInterface({
|
|
24
|
+
input: process.stdin,
|
|
25
|
+
output: process.stdout
|
|
26
|
+
});
|
|
27
|
+
const skillSrc = path.join(__dirname, 'SKILL.md');
|
|
28
|
+
const skillDest = path.resolve(__dirname, `../../../.github/skills/${packageName}/SKILL.md`);
|
|
29
|
+
if (!fs.existsSync(skillSrc)) {
|
|
30
|
+
console.error('SKILL.md not found in this package.');
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
rl.question(`This will copy SKILL.md to .github/skills/${packageName}/SKILL.md. Continue? (y/n): `, (answer) => {
|
|
34
|
+
if (answer.trim().toLowerCase() === 'y' || answer.trim().toLowerCase() === 'yes') {
|
|
35
|
+
fs.mkdirSync(path.dirname(skillDest), { recursive: true });
|
|
36
|
+
fs.copyFileSync(skillSrc, skillDest);
|
|
37
|
+
console.log(`SKILL.md installed to .github/skills/${packageName}/SKILL.md`);
|
|
38
|
+
} else {
|
|
39
|
+
console.log('Operation cancelled.');
|
|
40
|
+
}
|
|
41
|
+
rl.close();
|
|
42
|
+
});
|
|
43
|
+
} else {
|
|
44
|
+
console.log('Usage: <cli> get-readme | install-skill');
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
@@ -1,20 +1,12 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Utility type to expand a type's properties for better type inference and hover display.
|
|
3
|
-
* @template T - The type to expand.
|
|
4
|
-
*/
|
|
5
1
|
export type ExpandProps<T> = T extends infer O ? {
|
|
6
2
|
[K in keyof O]: O[K];
|
|
7
3
|
} : never;
|
|
8
|
-
/**
|
|
9
|
-
* Enumeration of primitive field types supported by the schema system.
|
|
10
|
-
* Used for type-safe field declarations in collection templates.
|
|
11
|
-
*/
|
|
12
4
|
export declare enum enumPrimitive {
|
|
13
5
|
id = "id",
|
|
14
6
|
any = "any",
|
|
15
7
|
date = "date",
|
|
16
8
|
text = "text",
|
|
17
|
-
number = "number"
|
|
9
|
+
number = "number",// IdbqModelCollectionTemplate
|
|
18
10
|
boolean = "boolean",
|
|
19
11
|
datetime = "datetime",
|
|
20
12
|
url = "url",
|
|
@@ -23,84 +15,24 @@ export declare enum enumPrimitive {
|
|
|
23
15
|
time = "time",
|
|
24
16
|
password = "password"
|
|
25
17
|
}
|
|
26
|
-
/**
|
|
27
|
-
* Enumeration of special field properties for schema fields.
|
|
28
|
-
* - private: Field is internal and not exposed externally.
|
|
29
|
-
* - readonly: Field cannot be modified after creation.
|
|
30
|
-
* - required: Field must be present in the data model.
|
|
31
|
-
*/
|
|
32
18
|
export declare enum TplProperties {
|
|
33
19
|
private = "private",
|
|
34
20
|
readonly = "readonly",
|
|
35
21
|
required = "required"
|
|
36
22
|
}
|
|
37
|
-
/**
|
|
38
|
-
* Recursively generates all possible space-separated combinations of a set of string literals.
|
|
39
|
-
* Used to create all valid combinations of field properties (e.g., 'private readonly', etc).
|
|
40
|
-
* @template T - The set of string literals to combine.
|
|
41
|
-
* @template U - The set of remaining string literals (for recursion).
|
|
42
|
-
*/
|
|
43
23
|
export type CombineElements<T extends string, U extends string = T> = T | (T extends any ? `${T} ${CombineElements<Exclude<U, T>>}` : never);
|
|
44
|
-
|
|
45
|
-
* Utility type to force TypeScript to expand a union or intersection for better hover display.
|
|
46
|
-
* @template T - The type to expand.
|
|
47
|
-
*/
|
|
48
|
-
type Expand<T> = T extends infer O ? {
|
|
49
|
-
[K in keyof O]: O[K];
|
|
50
|
-
} : never;
|
|
51
|
-
/**
|
|
52
|
-
* All valid combinations of TplProperties, including single and multi-property combinations.
|
|
53
|
-
* Used for field argument validation and schema typing.
|
|
54
|
-
*/
|
|
55
|
-
export type CombinedArgs = Expand<keyof typeof TplProperties | CombineElements<keyof typeof TplProperties>>;
|
|
56
|
-
/**
|
|
57
|
-
* Utility type to represent array or object wrappers for a given primitive type string.
|
|
58
|
-
* E.g., 'array-of-text', 'object-number'.
|
|
59
|
-
* @template T - The base type string.
|
|
60
|
-
*/
|
|
24
|
+
export type CombinedArgs = CombineElements<TplProperties>;
|
|
61
25
|
export type IdbObjectify<T extends string> = `array-of-${T}` | `object-${T}`;
|
|
62
|
-
/**
|
|
63
|
-
* Represents the fields of a collection template as a mapping from field name to type string.
|
|
64
|
-
*/
|
|
65
26
|
export type TplCollectionFields = Record<string, string>;
|
|
66
|
-
/**
|
|
67
|
-
* Represents all valid primitive field type strings for a collection field.
|
|
68
|
-
* Includes enumPrimitive keys, text variants, dot-paths, and foreign key references.
|
|
69
|
-
* @template T - (Unused, for future extension)
|
|
70
|
-
*/
|
|
71
27
|
export type TplFieldPrimitive<T = {}> = keyof typeof enumPrimitive | `text-${'tiny' | 'short' | 'medium' | 'long' | 'area'}` | `${string}.${string}` | `fk-${string}.${string}`;
|
|
72
|
-
/**
|
|
73
|
-
* Represents object or array wrappers for primitive field types.
|
|
74
|
-
*/
|
|
75
28
|
export type TplObjectFieldPrimitive = IdbObjectify<TplFieldPrimitive>;
|
|
76
|
-
/**
|
|
77
|
-
* Represents a foreign key field type string (e.g., 'fk-users.id').
|
|
78
|
-
*/
|
|
79
29
|
export type TplFieldFk = `fk-${string}.${string}`;
|
|
80
|
-
/**
|
|
81
|
-
* Represents object or array wrappers for foreign key field types.
|
|
82
|
-
*/
|
|
83
30
|
export type TplFkObject = IdbObjectify<TplFieldFk>;
|
|
84
|
-
/**
|
|
85
|
-
* Union of all valid field type strings for a collection field, including primitives, objects, and foreign keys.
|
|
86
|
-
*/
|
|
87
31
|
export type TplTypes = TplFieldPrimitive | TplObjectFieldPrimitive | TplFieldFk | TplFkObject;
|
|
88
|
-
/**
|
|
89
|
-
* Represents a field type string with property arguments, e.g., 'text (readonly required)'.
|
|
90
|
-
*/
|
|
91
32
|
export type TplFieldArgs = `${TplTypes} (${CombinedArgs})`;
|
|
92
|
-
/**
|
|
93
|
-
* Represents the allowed rules for a field: either a type string or a type string with arguments.
|
|
94
|
-
*/
|
|
33
|
+
/** rules */
|
|
95
34
|
export type TplFieldRules = TplFieldArgs | TplTypes;
|
|
96
|
-
/**
|
|
97
|
-
* Alias for TplFieldRules, used for clarity in some contexts.
|
|
98
|
-
*/
|
|
99
35
|
export type TplFieldType = TplFieldArgs | TplTypes;
|
|
100
|
-
/**
|
|
101
|
-
* Helper type for schema/field construction utilities.
|
|
102
|
-
* Used internally for dynamic schema building and validation.
|
|
103
|
-
*/
|
|
104
36
|
export type IDbForge = {
|
|
105
37
|
collection?: TplCollectionName;
|
|
106
38
|
fieldName?: keyof TplFields;
|
|
@@ -109,65 +41,23 @@ export type IDbForge = {
|
|
|
109
41
|
fieldArgs?: [keyof typeof TplProperties] | undefined;
|
|
110
42
|
is: any;
|
|
111
43
|
};
|
|
112
|
-
/**
|
|
113
|
-
* Main model type for describing the schema of an IndexedDB database.
|
|
114
|
-
* Maps collection names to their CollectionModel definitions.
|
|
115
|
-
* @template T - The shape of the collections in the database.
|
|
116
|
-
*/
|
|
117
44
|
export type IdbqModel<T = Record<string, Record<string, any>>> = {
|
|
118
45
|
readonly [K in keyof T]: CollectionModel<T[K]>;
|
|
119
46
|
};
|
|
120
|
-
/**
|
|
121
|
-
* Type alias for a collection name in the schema model.
|
|
122
|
-
*/
|
|
123
47
|
export type TplCollectionName<T = TplCollectionFields> = keyof IdbqModel<T>;
|
|
124
|
-
/**
|
|
125
|
-
* Type alias for the template property of a CollectionModel.
|
|
126
|
-
*/
|
|
127
48
|
export type Tpl<T = TplCollectionFields> = CollectionModel<T>['template'];
|
|
128
|
-
/**
|
|
129
|
-
* Type alias for the fields property of a CollectionModel's template.
|
|
130
|
-
*/
|
|
131
49
|
export type TplFields<T = TplCollectionFields> = CollectionModel<T>['template']['fields'];
|
|
132
|
-
/**
|
|
133
|
-
* Describes the structure and metadata for a single collection in the database schema.
|
|
134
|
-
* Includes keyPath, TypeScript type, and template (fields, indexes, FKs, etc).
|
|
135
|
-
* @template T - The shape of the collection's fields.
|
|
136
|
-
*/
|
|
137
50
|
export type CollectionModel<T = TplCollectionFields> = {
|
|
138
|
-
/**
|
|
139
|
-
* The key path (primary key) for the collection in IndexedDB.
|
|
140
|
-
*/
|
|
141
51
|
keyPath: string | any;
|
|
142
|
-
/**
|
|
143
|
-
* @deprecated Use 'ts' instead for type safety.
|
|
144
|
-
*/
|
|
52
|
+
/** @deprecated use ts instead */
|
|
145
53
|
model: any;
|
|
146
|
-
/**
|
|
147
|
-
* The TypeScript type representing the collection's data shape.
|
|
148
|
-
*/
|
|
149
54
|
ts: any;
|
|
150
|
-
/**
|
|
151
|
-
* Template metadata for the collection: fields, indexes, presentation, and foreign keys.
|
|
152
|
-
*/
|
|
153
55
|
template: {
|
|
154
|
-
/**
|
|
155
|
-
* The main index field for the collection.
|
|
156
|
-
*/
|
|
157
56
|
index: string;
|
|
158
|
-
/**
|
|
159
|
-
* Presentation string for UI or display purposes (combination of field names).
|
|
160
|
-
*/
|
|
161
57
|
presentation: CombineElements<Extract<keyof CollectionModel<T>['ts'], string>>;
|
|
162
|
-
/**
|
|
163
|
-
* Field definitions for the collection.
|
|
164
|
-
*/
|
|
165
58
|
fields: {
|
|
166
59
|
[K in keyof T]: TplFieldRules;
|
|
167
60
|
};
|
|
168
|
-
/**
|
|
169
|
-
* Foreign key definitions for the collection.
|
|
170
|
-
*/
|
|
171
61
|
fks: {
|
|
172
62
|
[K in TplCollectionName]?: {
|
|
173
63
|
code: K;
|
|
@@ -177,4 +67,3 @@ export type CollectionModel<T = TplCollectionFields> = {
|
|
|
177
67
|
};
|
|
178
68
|
};
|
|
179
69
|
};
|
|
180
|
-
export {};
|
package/dist/idbqlCore/types.js
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Enumeration of primitive field types supported by the schema system.
|
|
3
|
-
* Used for type-safe field declarations in collection templates.
|
|
4
|
-
*/
|
|
5
1
|
export var enumPrimitive;
|
|
6
2
|
(function (enumPrimitive) {
|
|
7
3
|
enumPrimitive["id"] = "id";
|
|
@@ -17,12 +13,6 @@ export var enumPrimitive;
|
|
|
17
13
|
enumPrimitive["time"] = "time";
|
|
18
14
|
enumPrimitive["password"] = "password";
|
|
19
15
|
})(enumPrimitive || (enumPrimitive = {}));
|
|
20
|
-
/**
|
|
21
|
-
* Enumeration of special field properties for schema fields.
|
|
22
|
-
* - private: Field is internal and not exposed externally.
|
|
23
|
-
* - readonly: Field cannot be modified after creation.
|
|
24
|
-
* - required: Field must be present in the data model.
|
|
25
|
-
*/
|
|
26
16
|
export var TplProperties;
|
|
27
17
|
(function (TplProperties) {
|
|
28
18
|
TplProperties["private"] = "private";
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export * from './state/idbstate.svelte.js';
|
|
2
2
|
export * from './state/idbqlEvent.svelte.js';
|
|
3
3
|
export * from './scripts/types.js';
|
|
4
|
+
export * from './path/pathResolver.js';
|
|
4
5
|
export * from './idbqlCore/types.js';
|
|
5
6
|
export * from './idbqlCore/idbqlSchema.js';
|
|
6
7
|
export * from './idbqlCore/idbqlCore.js';
|
|
7
|
-
export * from './path/pathResolver.js';
|
|
8
8
|
export * from './collection/collection.svelte.js';
|
package/dist/index.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
export * from './state/idbstate.svelte.js';
|
|
3
3
|
export * from './state/idbqlEvent.svelte.js';
|
|
4
4
|
export * from './scripts/types.js';
|
|
5
|
+
export * from './path/pathResolver.js';
|
|
5
6
|
export * from './idbqlCore/types.js';
|
|
6
7
|
export * from './idbqlCore/idbqlSchema.js';
|
|
7
8
|
export * from './idbqlCore/idbqlCore.js';
|
|
8
|
-
export * from './path/pathResolver.js';
|
|
9
9
|
export * from './collection/collection.svelte.js';
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { IdbqlIndexedCore } from
|
|
1
|
+
import type { IdbqlIndexedCore } from "../idbqlCore/idbqlCore.js";
|
|
2
2
|
interface IdbqlIndexedCore {
|
|
3
3
|
[key: string]: CollectionCore<any>;
|
|
4
4
|
}
|
|
5
|
-
import type { CollectionCore } from
|
|
6
|
-
import { type Where, type ResultSet, type ResultsetOptions } from
|
|
5
|
+
import type { CollectionCore } from "../collection/collection.svelte.js";
|
|
6
|
+
import { type Where, type ResultSet, type ResultsetOptions } from "@medyll/idae-query";
|
|
7
7
|
/**
|
|
8
8
|
* Main entry point.
|
|
9
9
|
* Creates a state object with indexedDB synchronization.
|
|
@@ -13,6 +13,7 @@ import { type Where, type ResultSet, type ResultsetOptions } from '@medyll/idae-
|
|
|
13
13
|
export declare const createIdbqlState: (idbBase: IdbqlIndexedCore) => {
|
|
14
14
|
collectionState: Record<string, CollectionState<any>>;
|
|
15
15
|
qolie: (collection: string) => {
|
|
16
|
+
put: (value: Partial<any>) => Promise<any>;
|
|
16
17
|
get: any;
|
|
17
18
|
getBy: (value: any, pathKey?: string) => ResultSet<any>;
|
|
18
19
|
getOne: any;
|
|
@@ -24,8 +25,6 @@ export declare const createIdbqlState: (idbBase: IdbqlIndexedCore) => {
|
|
|
24
25
|
where: (qy: Where<any>, options?: ResultsetOptions) => ResultSet<any>;
|
|
25
26
|
updateWhere: (where: Where<any>, data: Partial<any>) => Promise<boolean | undefined>;
|
|
26
27
|
};
|
|
27
|
-
onCollection: <T>(collectionName: string) => CollectionState<T>;
|
|
28
|
-
addCollection: <T>(collectionName: string) => CollectionState<T>;
|
|
29
28
|
};
|
|
30
29
|
/**
|
|
31
30
|
* Represents a dynamic state collection that interacts with an IndexedDB base.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { idbqlEvent } from
|
|
1
|
+
import { idbqlEvent } from "./idbqlEvent.svelte.js";
|
|
2
2
|
//
|
|
3
|
-
import { Operators, getResultset } from
|
|
3
|
+
import { Operators, getResultset, } from "@medyll/idae-query";
|
|
4
4
|
/**
|
|
5
5
|
* Main entry point.
|
|
6
6
|
* Creates a state object with indexedDB synchronization.
|
|
@@ -16,6 +16,7 @@ export const createIdbqlState = (idbBase) => {
|
|
|
16
16
|
if (!collections[collection])
|
|
17
17
|
throw new Error(`Collection ${collection} not found`);
|
|
18
18
|
return {
|
|
19
|
+
put: collections[collection].put,
|
|
19
20
|
get: collections[collection].get,
|
|
20
21
|
getBy: collections[collection].getBy,
|
|
21
22
|
getOne: collections[collection].getOne,
|
|
@@ -25,7 +26,7 @@ export const createIdbqlState = (idbBase) => {
|
|
|
25
26
|
deleteWhere: collections[collection].deleteWhere,
|
|
26
27
|
update: collections[collection].update,
|
|
27
28
|
where: collections[collection].where,
|
|
28
|
-
updateWhere: collections[collection].updateWhere
|
|
29
|
+
updateWhere: collections[collection].updateWhere,
|
|
29
30
|
};
|
|
30
31
|
};
|
|
31
32
|
function addCollection(collectionName) {
|
|
@@ -40,8 +41,6 @@ export const createIdbqlState = (idbBase) => {
|
|
|
40
41
|
return {
|
|
41
42
|
collectionState: collections,
|
|
42
43
|
qolie: qolie,
|
|
43
|
-
onCollection: addCollection,
|
|
44
|
-
addCollection: addCollection
|
|
45
44
|
};
|
|
46
45
|
};
|
|
47
46
|
/**
|
|
@@ -121,7 +120,7 @@ export class CollectionState {
|
|
|
121
120
|
* @returns {T | undefined} The item found, or undefined if not found.
|
|
122
121
|
*/
|
|
123
122
|
get get() {
|
|
124
|
-
return (value, pathKey =
|
|
123
|
+
return (value, pathKey = "id") => {
|
|
125
124
|
return this.where({ [pathKey]: value })?.[0];
|
|
126
125
|
};
|
|
127
126
|
}
|
|
@@ -131,7 +130,7 @@ export class CollectionState {
|
|
|
131
130
|
* @param {string} [pathKey="id"] - The key to search by.
|
|
132
131
|
* @returns {ResultSet<T>} The result set of the query.
|
|
133
132
|
*/
|
|
134
|
-
getBy(value, pathKey =
|
|
133
|
+
getBy(value, pathKey = "id") {
|
|
135
134
|
return this.where({ [pathKey]: value });
|
|
136
135
|
}
|
|
137
136
|
/**
|
|
@@ -142,7 +141,7 @@ export class CollectionState {
|
|
|
142
141
|
* @returns {T | undefined} The item found, or undefined if not found.
|
|
143
142
|
*/
|
|
144
143
|
get getOne() {
|
|
145
|
-
return (value, pathKey =
|
|
144
|
+
return (value, pathKey = "id") => {
|
|
146
145
|
return this.where({ [pathKey]: value })?.[0];
|
|
147
146
|
};
|
|
148
147
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@medyll/idae-idbql",
|
|
3
|
+
"bin": {
|
|
4
|
+
"idae-idbql": "./cli.js"
|
|
5
|
+
},
|
|
3
6
|
"scope": "@medyll",
|
|
4
|
-
"
|
|
7
|
+
"author": "Lebrun Meddy",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/medyll/idae.git"
|
|
11
|
+
},
|
|
12
|
+
"version": "0.185.2",
|
|
5
13
|
"description": "A powerful and flexible IndexedDB query library for TypeScript and JavaScript applications, offering a MongoDB-like query interface, strong TypeScript support, reactive state management, and easy integration with front-end frameworks like Svelte.",
|
|
6
14
|
"exports": {
|
|
7
15
|
".": {
|
|
@@ -20,7 +28,12 @@
|
|
|
20
28
|
"peerDependencies": {
|
|
21
29
|
"svelte": "^5.0.0-next"
|
|
22
30
|
},
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public",
|
|
33
|
+
"directory": "."
|
|
34
|
+
},
|
|
23
35
|
"devDependencies": {
|
|
36
|
+
"@semantic-release/github": "^10.3.5",
|
|
24
37
|
"@sveltejs/adapter-auto": "^6.0.0",
|
|
25
38
|
"@sveltejs/kit": "^2.20.7",
|
|
26
39
|
"@sveltejs/package": "^2.3.11",
|
|
@@ -30,8 +43,8 @@
|
|
|
30
43
|
"tslib": "^2.8.1",
|
|
31
44
|
"typescript": "^5.8.3",
|
|
32
45
|
"vite": "^6.3.2",
|
|
33
|
-
"@medyll/idae-
|
|
34
|
-
"@medyll/idae-query": "0.
|
|
46
|
+
"@medyll/idae-eslint-config": "0.1.5",
|
|
47
|
+
"@medyll/idae-query": "0.186.2"
|
|
35
48
|
},
|
|
36
49
|
"svelte": "./dist/index.js",
|
|
37
50
|
"types": "./dist/index.d.ts",
|
|
@@ -45,6 +58,6 @@
|
|
|
45
58
|
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
46
59
|
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
|
47
60
|
"test": "vitest",
|
|
48
|
-
"
|
|
61
|
+
"prepackage": "node scripts/package-pre.js"
|
|
49
62
|
}
|
|
50
63
|
}
|