@moltendb-web/angular 1.0.0-rc.5
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 +189 -0
- package/dist/angular/README.md +189 -0
- package/dist/angular/esm2022/lib/moltendb.client.mjs +10 -0
- package/dist/angular/esm2022/lib/moltendb.provider.mjs +8 -0
- package/dist/angular/esm2022/lib/moltendb.resource.mjs +47 -0
- package/dist/angular/esm2022/lib/moltendb.service.mjs +30 -0
- package/dist/angular/esm2022/moltendb-web-angular.mjs +5 -0
- package/dist/angular/esm2022/public-api.mjs +7 -0
- package/dist/angular/fesm2022/moltendb-web-angular.mjs +100 -0
- package/dist/angular/fesm2022/moltendb-web-angular.mjs.map +1 -0
- package/dist/angular/index.d.ts +5 -0
- package/dist/angular/lib/moltendb.client.d.ts +6 -0
- package/dist/angular/lib/moltendb.provider.d.ts +7 -0
- package/dist/angular/lib/moltendb.resource.d.ts +8 -0
- package/dist/angular/lib/moltendb.service.d.ts +11 -0
- package/dist/angular/public-api.d.ts +3 -0
- package/ng-package.json +7 -0
- package/package.json +28 -0
- package/src/lib/moltendb.client.ts +11 -0
- package/src/lib/moltendb.provider.ts +14 -0
- package/src/lib/moltendb.resource.ts +59 -0
- package/src/lib/moltendb.service.ts +28 -0
- package/src/public-api.ts +7 -0
- package/tsconfig.json +21 -0
- package/tsconfig.lib.json +10 -0
package/README.md
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# @moltendb-web/angular
|
|
2
|
+
|
|
3
|
+
The official Angular integration for MoltenDb, providing a seamless, highly reactive developer experience using modern Angular Signals.
|
|
4
|
+
|
|
5
|
+
This package bridges the gap between MoltenDb's powerful Web Worker/WASM engine and your Angular UI, offering auto-updating data resources, built-in loading states, and elegant functional dependency injection.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @moltendb-web/core @moltendb-web/query @moltendb-web/angular
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Step 1: Configure Assets (Crucial)
|
|
18
|
+
|
|
19
|
+
MoltenDb runs its database engine inside a background Web Worker and relies on WebAssembly (WASM). You must tell Angular to serve these compiled files as public assets so the browser can load them.
|
|
20
|
+
|
|
21
|
+
Update the `assets` array in your `angular.json` to include the MoltenDb distribution files:
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
"assets": [
|
|
25
|
+
{
|
|
26
|
+
"glob": "moltendb-worker.js",
|
|
27
|
+
"input": "node_modules/@moltendb-web/core/dist",
|
|
28
|
+
"output": "/"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"glob": "moltendb.js",
|
|
32
|
+
"input": "node_modules/@moltendb-web/core/dist/wasm",
|
|
33
|
+
"output": "/wasm/"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"glob": "*.wasm",
|
|
37
|
+
"input": "node_modules/@moltendb-web/core/dist/wasm",
|
|
38
|
+
"output": "/wasm/"
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
> **Note:** Restart your Angular dev server after modifying `angular.json`.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Step 2: Provide MoltenDb
|
|
48
|
+
|
|
49
|
+
Initialize MoltenDb in your app's root configuration (`app.config.ts`). This boots the engine, handles leader election across tabs, and makes the database available to your entire application.
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
import { ApplicationConfig } from '@angular/core';
|
|
53
|
+
import { provideMoltenDb } from '@moltendb-web/angular';
|
|
54
|
+
|
|
55
|
+
export const appConfig: ApplicationConfig = {
|
|
56
|
+
providers: [
|
|
57
|
+
provideMoltenDb({
|
|
58
|
+
name: 'local_test_db',
|
|
59
|
+
workerUrl: '/moltendb-worker.js' // Points to the asset we exposed in Step 1
|
|
60
|
+
})
|
|
61
|
+
]
|
|
62
|
+
};
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Step 3: Fetching and Mutating Data
|
|
68
|
+
|
|
69
|
+
This library provides two distinct ways to interact with your database, depending on whether you are binding data to the UI or performing background mutations.
|
|
70
|
+
|
|
71
|
+
### 1. The Reactive Way: `moltenDbResource`
|
|
72
|
+
|
|
73
|
+
Use `moltenDbResource` when you want to display data in your template. It automatically handles loading states, catches errors, and listens for live database changes to keep your UI instantly synced across tabs.
|
|
74
|
+
|
|
75
|
+
It pre-binds the collection for you, keeping your queries incredibly clean. The query function receives the pre-bound `collection` and the full `client` as arguments:
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
import { Component } from '@angular/core';
|
|
79
|
+
import { moltenDbResource } from '@moltendb-web/angular';
|
|
80
|
+
|
|
81
|
+
interface UserDoc {
|
|
82
|
+
_key: string;
|
|
83
|
+
name: string;
|
|
84
|
+
role: string;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
@Component({
|
|
88
|
+
selector: 'app-users',
|
|
89
|
+
template: `
|
|
90
|
+
@if (users.isLoading() && !users.value()) {
|
|
91
|
+
<p>Loading...</p>
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
@if (users.value(); as userList) {
|
|
95
|
+
<ul>
|
|
96
|
+
@for (user of userList; track user._key) {
|
|
97
|
+
<li>{{ user.name }} ({{ user.role }})</li>
|
|
98
|
+
}
|
|
99
|
+
</ul>
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
@if (users.error()) {
|
|
103
|
+
<div class="alert">{{ users.error().message }}</div>
|
|
104
|
+
}
|
|
105
|
+
`
|
|
106
|
+
})
|
|
107
|
+
export class UsersComponent {
|
|
108
|
+
// ⚡ The resource automatically fetches and updates when 'users' changes!
|
|
109
|
+
users = moltenDbResource<UserDoc[]>('users', async (collection) => {
|
|
110
|
+
console.log('Fetching users...');
|
|
111
|
+
const result = await collection.get().exec();
|
|
112
|
+
return result as unknown as UserDoc[];
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The returned `MoltenDbResource<T>` object exposes three readonly signals:
|
|
118
|
+
|
|
119
|
+
| Signal | Type | Description |
|
|
120
|
+
|---|---|---|
|
|
121
|
+
| `value` | `Signal<T \| undefined>` | The latest query result |
|
|
122
|
+
| `isLoading` | `Signal<boolean>` | `true` while a fetch is in progress |
|
|
123
|
+
| `error` | `Signal<any \| null>` | The last error, or `null` if none |
|
|
124
|
+
|
|
125
|
+
### 2. The Imperative Way: `moltendbClient()`
|
|
126
|
+
|
|
127
|
+
Use the `moltendbClient()` injection hook when you need to write data, perform one-off queries in response to user actions (like button clicks), or run complex logic outside of the reactive UI flow.
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
import { Component } from '@angular/core';
|
|
131
|
+
import { moltendbClient } from '@moltendb-web/angular';
|
|
132
|
+
|
|
133
|
+
@Component({
|
|
134
|
+
// ...
|
|
135
|
+
})
|
|
136
|
+
export class AdminComponent {
|
|
137
|
+
// ⚡ Grab direct, imperative access to the Query Client
|
|
138
|
+
private client = moltendbClient();
|
|
139
|
+
|
|
140
|
+
async addUser() {
|
|
141
|
+
const randomId = Math.random().toString(36).substring(2, 9);
|
|
142
|
+
|
|
143
|
+
// Direct, imperative database mutation
|
|
144
|
+
await this.client.collection('users').set({
|
|
145
|
+
[randomId]: {
|
|
146
|
+
name: 'Angular Dev ' + randomId,
|
|
147
|
+
role: 'Admin'
|
|
148
|
+
}
|
|
149
|
+
}).exec();
|
|
150
|
+
|
|
151
|
+
// Note: Any moltenDbResource listening to the 'users' collection
|
|
152
|
+
// will automatically refresh instantly after this set()!
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
async getUsers() {
|
|
156
|
+
// One-off imperative commands
|
|
157
|
+
const allUsers = await this.client.collection('users').get().exec();
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## API Reference
|
|
165
|
+
|
|
166
|
+
### `provideMoltenDb(config)`
|
|
167
|
+
|
|
168
|
+
Registers MoltenDb as an Angular environment provider. Call this once in your root `app.config.ts`.
|
|
169
|
+
|
|
170
|
+
| Option | Type | Description |
|
|
171
|
+
|---|---|---|
|
|
172
|
+
| `name` | `string` | The name of the database |
|
|
173
|
+
| `workerUrl` | `string` | URL to the `moltendb-worker.js` asset |
|
|
174
|
+
|
|
175
|
+
### `moltenDbResource<T>(collection, queryFn)`
|
|
176
|
+
|
|
177
|
+
Creates a reactive resource bound to a collection. Must be called in an injection context (e.g. inside a component class field initializer).
|
|
178
|
+
|
|
179
|
+
| Parameter | Type | Description |
|
|
180
|
+
|---|---|---|
|
|
181
|
+
| `collection` | `string` | The collection name to bind to |
|
|
182
|
+
| `queryFn` | `(collection, client) => Promise<T>` | Async function receiving the pre-bound collection and the full `MoltenDbClient` |
|
|
183
|
+
|
|
184
|
+
Returns a `MoltenDbResource<T>` with `value`, `isLoading`, and `error` signals.
|
|
185
|
+
|
|
186
|
+
### `moltendbClient()`
|
|
187
|
+
|
|
188
|
+
An injection hook that returns the underlying `MoltenDbClient` instance for imperative database access. Must be called in an injection context.
|
|
189
|
+
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# @moltendb-web/angular
|
|
2
|
+
|
|
3
|
+
The official Angular integration for MoltenDb, providing a seamless, highly reactive developer experience using modern Angular Signals.
|
|
4
|
+
|
|
5
|
+
This package bridges the gap between MoltenDb's powerful Web Worker/WASM engine and your Angular UI, offering auto-updating data resources, built-in loading states, and elegant functional dependency injection.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @moltendb-web/core @moltendb-web/query @moltendb-web/angular
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Step 1: Configure Assets (Crucial)
|
|
18
|
+
|
|
19
|
+
MoltenDb runs its database engine inside a background Web Worker and relies on WebAssembly (WASM). You must tell Angular to serve these compiled files as public assets so the browser can load them.
|
|
20
|
+
|
|
21
|
+
Update the `assets` array in your `angular.json` to include the MoltenDb distribution files:
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
"assets": [
|
|
25
|
+
{
|
|
26
|
+
"glob": "moltendb-worker.js",
|
|
27
|
+
"input": "node_modules/@moltendb-web/core/dist",
|
|
28
|
+
"output": "/"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"glob": "moltendb.js",
|
|
32
|
+
"input": "node_modules/@moltendb-web/core/dist/wasm",
|
|
33
|
+
"output": "/wasm/"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"glob": "*.wasm",
|
|
37
|
+
"input": "node_modules/@moltendb-web/core/dist/wasm",
|
|
38
|
+
"output": "/wasm/"
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
> **Note:** Restart your Angular dev server after modifying `angular.json`.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Step 2: Provide MoltenDb
|
|
48
|
+
|
|
49
|
+
Initialize MoltenDb in your app's root configuration (`app.config.ts`). This boots the engine, handles leader election across tabs, and makes the database available to your entire application.
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
import { ApplicationConfig } from '@angular/core';
|
|
53
|
+
import { provideMoltenDb } from '@moltendb-web/angular';
|
|
54
|
+
|
|
55
|
+
export const appConfig: ApplicationConfig = {
|
|
56
|
+
providers: [
|
|
57
|
+
provideMoltenDb({
|
|
58
|
+
name: 'local_test_db',
|
|
59
|
+
workerUrl: '/moltendb-worker.js' // Points to the asset we exposed in Step 1
|
|
60
|
+
})
|
|
61
|
+
]
|
|
62
|
+
};
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Step 3: Fetching and Mutating Data
|
|
68
|
+
|
|
69
|
+
This library provides two distinct ways to interact with your database, depending on whether you are binding data to the UI or performing background mutations.
|
|
70
|
+
|
|
71
|
+
### 1. The Reactive Way: `moltenDbResource`
|
|
72
|
+
|
|
73
|
+
Use `moltenDbResource` when you want to display data in your template. It automatically handles loading states, catches errors, and listens for live database changes to keep your UI instantly synced across tabs.
|
|
74
|
+
|
|
75
|
+
It pre-binds the collection for you, keeping your queries incredibly clean. The query function receives the pre-bound `collection` and the full `client` as arguments:
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
import { Component } from '@angular/core';
|
|
79
|
+
import { moltenDbResource } from '@moltendb-web/angular';
|
|
80
|
+
|
|
81
|
+
interface UserDoc {
|
|
82
|
+
_key: string;
|
|
83
|
+
name: string;
|
|
84
|
+
role: string;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
@Component({
|
|
88
|
+
selector: 'app-users',
|
|
89
|
+
template: `
|
|
90
|
+
@if (users.isLoading() && !users.value()) {
|
|
91
|
+
<p>Loading...</p>
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
@if (users.value(); as userList) {
|
|
95
|
+
<ul>
|
|
96
|
+
@for (user of userList; track user._key) {
|
|
97
|
+
<li>{{ user.name }} ({{ user.role }})</li>
|
|
98
|
+
}
|
|
99
|
+
</ul>
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
@if (users.error()) {
|
|
103
|
+
<div class="alert">{{ users.error().message }}</div>
|
|
104
|
+
}
|
|
105
|
+
`
|
|
106
|
+
})
|
|
107
|
+
export class UsersComponent {
|
|
108
|
+
// ⚡ The resource automatically fetches and updates when 'users' changes!
|
|
109
|
+
users = moltenDbResource<UserDoc[]>('users', async (collection) => {
|
|
110
|
+
console.log('Fetching users...');
|
|
111
|
+
const result = await collection.get().exec();
|
|
112
|
+
return result as unknown as UserDoc[];
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The returned `MoltenDbResource<T>` object exposes three readonly signals:
|
|
118
|
+
|
|
119
|
+
| Signal | Type | Description |
|
|
120
|
+
|---|---|---|
|
|
121
|
+
| `value` | `Signal<T \| undefined>` | The latest query result |
|
|
122
|
+
| `isLoading` | `Signal<boolean>` | `true` while a fetch is in progress |
|
|
123
|
+
| `error` | `Signal<any \| null>` | The last error, or `null` if none |
|
|
124
|
+
|
|
125
|
+
### 2. The Imperative Way: `moltendbClient()`
|
|
126
|
+
|
|
127
|
+
Use the `moltendbClient()` injection hook when you need to write data, perform one-off queries in response to user actions (like button clicks), or run complex logic outside of the reactive UI flow.
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
import { Component } from '@angular/core';
|
|
131
|
+
import { moltendbClient } from '@moltendb-web/angular';
|
|
132
|
+
|
|
133
|
+
@Component({
|
|
134
|
+
// ...
|
|
135
|
+
})
|
|
136
|
+
export class AdminComponent {
|
|
137
|
+
// ⚡ Grab direct, imperative access to the Query Client
|
|
138
|
+
private client = moltendbClient();
|
|
139
|
+
|
|
140
|
+
async addUser() {
|
|
141
|
+
const randomId = Math.random().toString(36).substring(2, 9);
|
|
142
|
+
|
|
143
|
+
// Direct, imperative database mutation
|
|
144
|
+
await this.client.collection('users').set({
|
|
145
|
+
[randomId]: {
|
|
146
|
+
name: 'Angular Dev ' + randomId,
|
|
147
|
+
role: 'Admin'
|
|
148
|
+
}
|
|
149
|
+
}).exec();
|
|
150
|
+
|
|
151
|
+
// Note: Any moltenDbResource listening to the 'users' collection
|
|
152
|
+
// will automatically refresh instantly after this set()!
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
async getUsers() {
|
|
156
|
+
// One-off imperative commands
|
|
157
|
+
const allUsers = await this.client.collection('users').get().exec();
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## API Reference
|
|
165
|
+
|
|
166
|
+
### `provideMoltenDb(config)`
|
|
167
|
+
|
|
168
|
+
Registers MoltenDb as an Angular environment provider. Call this once in your root `app.config.ts`.
|
|
169
|
+
|
|
170
|
+
| Option | Type | Description |
|
|
171
|
+
|---|---|---|
|
|
172
|
+
| `name` | `string` | The name of the database |
|
|
173
|
+
| `workerUrl` | `string` | URL to the `moltendb-worker.js` asset |
|
|
174
|
+
|
|
175
|
+
### `moltenDbResource<T>(collection, queryFn)`
|
|
176
|
+
|
|
177
|
+
Creates a reactive resource bound to a collection. Must be called in an injection context (e.g. inside a component class field initializer).
|
|
178
|
+
|
|
179
|
+
| Parameter | Type | Description |
|
|
180
|
+
|---|---|---|
|
|
181
|
+
| `collection` | `string` | The collection name to bind to |
|
|
182
|
+
| `queryFn` | `(collection, client) => Promise<T>` | Async function receiving the pre-bound collection and the full `MoltenDbClient` |
|
|
183
|
+
|
|
184
|
+
Returns a `MoltenDbResource<T>` with `value`, `isLoading`, and `error` signals.
|
|
185
|
+
|
|
186
|
+
### `moltendbClient()`
|
|
187
|
+
|
|
188
|
+
An injection hook that returns the underlying `MoltenDbClient` instance for imperative database access. Must be called in an injection context.
|
|
189
|
+
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { inject } from '@angular/core';
|
|
2
|
+
import { MoltenDbService } from './moltendb.service';
|
|
3
|
+
/**
|
|
4
|
+
* Functional injection hook to access the MoltenDb Query Client.
|
|
5
|
+
* Removes the need to manually inject MoltenDbService in components.
|
|
6
|
+
*/
|
|
7
|
+
export function moltendbClient() {
|
|
8
|
+
return inject(MoltenDbService).client;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9sdGVuZGIuY2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9tb2x0ZW5kYi5jbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUV2QyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFckQ7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLGNBQWM7SUFDNUIsT0FBTyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUMsTUFBTSxDQUFDO0FBQ3hDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE1vbHRlbkRiQ2xpZW50IH0gZnJvbSAnQG1vbHRlbmRiLXdlYi9xdWVyeSc7XG5pbXBvcnQgeyBNb2x0ZW5EYlNlcnZpY2UgfSBmcm9tICcuL21vbHRlbmRiLnNlcnZpY2UnO1xuXG4vKipcbiAqIEZ1bmN0aW9uYWwgaW5qZWN0aW9uIGhvb2sgdG8gYWNjZXNzIHRoZSBNb2x0ZW5EYiBRdWVyeSBDbGllbnQuXG4gKiBSZW1vdmVzIHRoZSBuZWVkIHRvIG1hbnVhbGx5IGluamVjdCBNb2x0ZW5EYlNlcnZpY2UgaW4gY29tcG9uZW50cy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1vbHRlbmRiQ2xpZW50KCk6IE1vbHRlbkRiQ2xpZW50IHtcbiAgcmV0dXJuIGluamVjdChNb2x0ZW5EYlNlcnZpY2UpLmNsaWVudDtcbn0iXX0=
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { InjectionToken, makeEnvironmentProviders } from '@angular/core';
|
|
2
|
+
export const MOLTEN_CONFIG = new InjectionToken('MOLTEN_CONFIG');
|
|
3
|
+
export function provideMoltenDb(config) {
|
|
4
|
+
return makeEnvironmentProviders([
|
|
5
|
+
{ provide: MOLTEN_CONFIG, useValue: config }
|
|
6
|
+
]);
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9sdGVuZGIucHJvdmlkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL21vbHRlbmRiLnByb3ZpZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBd0IsY0FBYyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBTy9GLE1BQU0sQ0FBQyxNQUFNLGFBQWEsR0FBRyxJQUFJLGNBQWMsQ0FBeUIsZUFBZSxDQUFDLENBQUM7QUFFekYsTUFBTSxVQUFVLGVBQWUsQ0FBQyxNQUE4QjtJQUM1RCxPQUFPLHdCQUF3QixDQUFDO1FBQzlCLEVBQUUsT0FBTyxFQUFFLGFBQWEsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFO0tBQzdDLENBQUMsQ0FBQztBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBFbnZpcm9ubWVudFByb3ZpZGVycywgSW5qZWN0aW9uVG9rZW4sIG1ha2VFbnZpcm9ubWVudFByb3ZpZGVycyB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTW9sdGVuRGJPcHRpb25zIH0gZnJvbSAnQG1vbHRlbmRiLXdlYi9jb3JlJztcblxuZXhwb3J0IGludGVyZmFjZSBBbmd1bGFyTW9sdGVuRGJPcHRpb25zIGV4dGVuZHMgTW9sdGVuRGJPcHRpb25zIHtcbiAgbmFtZTogc3RyaW5nO1xufVxuXG5leHBvcnQgY29uc3QgTU9MVEVOX0NPTkZJRyA9IG5ldyBJbmplY3Rpb25Ub2tlbjxBbmd1bGFyTW9sdGVuRGJPcHRpb25zPignTU9MVEVOX0NPTkZJRycpO1xuXG5leHBvcnQgZnVuY3Rpb24gcHJvdmlkZU1vbHRlbkRiKGNvbmZpZzogQW5ndWxhck1vbHRlbkRiT3B0aW9ucyk6IEVudmlyb25tZW50UHJvdmlkZXJzIHtcbiAgcmV0dXJuIG1ha2VFbnZpcm9ubWVudFByb3ZpZGVycyhbXG4gICAgeyBwcm92aWRlOiBNT0xURU5fQ09ORklHLCB1c2VWYWx1ZTogY29uZmlnIH1cbiAgXSk7XG59Il19
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { inject, signal, effect, untracked } from '@angular/core';
|
|
2
|
+
import { MoltenDbService } from './moltendb.service';
|
|
3
|
+
export function moltenDbResource(collection,
|
|
4
|
+
// Automatically infer the return type of .collection()
|
|
5
|
+
queryFn) {
|
|
6
|
+
const molten = inject(MoltenDbService);
|
|
7
|
+
const value = signal(undefined);
|
|
8
|
+
const isLoading = signal(false);
|
|
9
|
+
const error = signal(null);
|
|
10
|
+
const fetchData = async () => {
|
|
11
|
+
untracked(() => isLoading.set(true));
|
|
12
|
+
try {
|
|
13
|
+
// ⚡ Pre-bind the collection and pass it in!
|
|
14
|
+
const result = await queryFn(molten.client.collection(collection), molten.client);
|
|
15
|
+
value.set(result);
|
|
16
|
+
error.set(null);
|
|
17
|
+
}
|
|
18
|
+
catch (err) {
|
|
19
|
+
if (err.message?.includes('404')) {
|
|
20
|
+
value.set([]);
|
|
21
|
+
error.set(null);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
error.set(err);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
finally {
|
|
28
|
+
isLoading.set(false);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
effect((onCleanup) => {
|
|
32
|
+
if (!molten.isReady())
|
|
33
|
+
return;
|
|
34
|
+
fetchData();
|
|
35
|
+
const unsubscribe = molten.db.subscribe((evt) => {
|
|
36
|
+
if (evt.collection === collection)
|
|
37
|
+
fetchData();
|
|
38
|
+
});
|
|
39
|
+
onCleanup(() => unsubscribe());
|
|
40
|
+
});
|
|
41
|
+
return {
|
|
42
|
+
value: value.asReadonly(),
|
|
43
|
+
isLoading: isLoading.asReadonly(),
|
|
44
|
+
error: error.asReadonly()
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9sdGVuZGIucmVzb3VyY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL21vbHRlbmRiLnJlc291cmNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBVSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFMUUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBUXJELE1BQU0sVUFBVSxnQkFBZ0IsQ0FDNUIsVUFBa0I7QUFDbEIsd0RBQXdEO0FBQ3hELE9BQXFHO0lBRXZHLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUV2QyxNQUFNLEtBQUssR0FBRyxNQUFNLENBQWdCLFNBQVMsQ0FBQyxDQUFDO0lBQy9DLE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBVSxLQUFLLENBQUMsQ0FBQztJQUN6QyxNQUFNLEtBQUssR0FBRyxNQUFNLENBQWEsSUFBSSxDQUFDLENBQUM7SUFFdkMsTUFBTSxTQUFTLEdBQUcsS0FBSyxJQUFJLEVBQUU7UUFDM0IsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUVyQyxJQUFJLENBQUM7WUFDSCw0Q0FBNEM7WUFDNUMsTUFBTSxNQUFNLEdBQUcsTUFBTSxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ2xGLEtBQUssQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDbEIsS0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNsQixDQUFDO1FBQUMsT0FBTyxHQUFRLEVBQUUsQ0FBQztZQUNsQixJQUFJLEdBQUcsQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQ2pDLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBUyxDQUFDLENBQUM7Z0JBQ3JCLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDbEIsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDakIsQ0FBQztRQUNILENBQUM7Z0JBQVMsQ0FBQztZQUNULFNBQVMsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDdkIsQ0FBQztJQUNILENBQUMsQ0FBQztJQUVGLE1BQU0sQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFO1FBQ25CLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFO1lBQUUsT0FBTztRQUU5QixTQUFTLEVBQUUsQ0FBQztRQUVaLE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUU7WUFDOUMsSUFBSSxHQUFHLENBQUMsVUFBVSxLQUFLLFVBQVU7Z0JBQUUsU0FBUyxFQUFFLENBQUM7UUFDakQsQ0FBQyxDQUFDLENBQUM7UUFFSCxTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztJQUNqQyxDQUFDLENBQUMsQ0FBQztJQUVILE9BQU87UUFDTCxLQUFLLEVBQUUsS0FBSyxDQUFDLFVBQVUsRUFBRTtRQUN6QixTQUFTLEVBQUUsU0FBUyxDQUFDLFVBQVUsRUFBRTtRQUNqQyxLQUFLLEVBQUUsS0FBSyxDQUFDLFVBQVUsRUFBRTtLQUMxQixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGluamVjdCwgc2lnbmFsLCBlZmZlY3QsIFNpZ25hbCwgdW50cmFja2VkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBNb2x0ZW5EYkNsaWVudCB9IGZyb20gJ0Btb2x0ZW5kYi13ZWIvcXVlcnknO1xuaW1wb3J0IHsgTW9sdGVuRGJTZXJ2aWNlIH0gZnJvbSAnLi9tb2x0ZW5kYi5zZXJ2aWNlJztcblxuZXhwb3J0IGludGVyZmFjZSBNb2x0ZW5EYlJlc291cmNlPFQ+IHtcbiAgdmFsdWU6IFNpZ25hbDxUIHwgdW5kZWZpbmVkPjtcbiAgaXNMb2FkaW5nOiBTaWduYWw8Ym9vbGVhbj47XG4gIGVycm9yOiBTaWduYWw8YW55IHwgbnVsbD47XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtb2x0ZW5EYlJlc291cmNlPFQ+KFxuICAgIGNvbGxlY3Rpb246IHN0cmluZyxcbiAgICAvLyAgQXV0b21hdGljYWxseSBpbmZlciB0aGUgcmV0dXJuIHR5cGUgb2YgLmNvbGxlY3Rpb24oKVxuICAgIHF1ZXJ5Rm46IChjb2xsZWN0aW9uOiBSZXR1cm5UeXBlPE1vbHRlbkRiQ2xpZW50Wydjb2xsZWN0aW9uJ10+LCBjbGllbnQ6IE1vbHRlbkRiQ2xpZW50KSA9PiBQcm9taXNlPFQ+XG4pOiBNb2x0ZW5EYlJlc291cmNlPFQ+IHtcbiAgY29uc3QgbW9sdGVuID0gaW5qZWN0KE1vbHRlbkRiU2VydmljZSk7XG5cbiAgY29uc3QgdmFsdWUgPSBzaWduYWw8VCB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcbiAgY29uc3QgaXNMb2FkaW5nID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcbiAgY29uc3QgZXJyb3IgPSBzaWduYWw8YW55IHwgbnVsbD4obnVsbCk7XG5cbiAgY29uc3QgZmV0Y2hEYXRhID0gYXN5bmMgKCkgPT4ge1xuICAgIHVudHJhY2tlZCgoKSA9PiBpc0xvYWRpbmcuc2V0KHRydWUpKTtcblxuICAgIHRyeSB7XG4gICAgICAvLyDimqEgUHJlLWJpbmQgdGhlIGNvbGxlY3Rpb24gYW5kIHBhc3MgaXQgaW4hXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBxdWVyeUZuKG1vbHRlbi5jbGllbnQuY29sbGVjdGlvbihjb2xsZWN0aW9uKSwgbW9sdGVuLmNsaWVudCk7XG4gICAgICB2YWx1ZS5zZXQocmVzdWx0KTtcbiAgICAgIGVycm9yLnNldChudWxsKTtcbiAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgaWYgKGVyci5tZXNzYWdlPy5pbmNsdWRlcygnNDA0JykpIHtcbiAgICAgICAgdmFsdWUuc2V0KFtdIGFzIGFueSk7XG4gICAgICAgIGVycm9yLnNldChudWxsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVycm9yLnNldChlcnIpO1xuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICBpc0xvYWRpbmcuc2V0KGZhbHNlKTtcbiAgICB9XG4gIH07XG5cbiAgZWZmZWN0KChvbkNsZWFudXApID0+IHtcbiAgICBpZiAoIW1vbHRlbi5pc1JlYWR5KCkpIHJldHVybjtcblxuICAgIGZldGNoRGF0YSgpO1xuXG4gICAgY29uc3QgdW5zdWJzY3JpYmUgPSBtb2x0ZW4uZGIuc3Vic2NyaWJlKChldnQpID0+IHtcbiAgICAgIGlmIChldnQuY29sbGVjdGlvbiA9PT0gY29sbGVjdGlvbikgZmV0Y2hEYXRhKCk7XG4gICAgfSk7XG5cbiAgICBvbkNsZWFudXAoKCkgPT4gdW5zdWJzY3JpYmUoKSk7XG4gIH0pO1xuXG4gIHJldHVybiB7XG4gICAgdmFsdWU6IHZhbHVlLmFzUmVhZG9ubHkoKSxcbiAgICBpc0xvYWRpbmc6IGlzTG9hZGluZy5hc1JlYWRvbmx5KCksXG4gICAgZXJyb3I6IGVycm9yLmFzUmVhZG9ubHkoKVxuICB9O1xufSJdfQ==
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Injectable, inject, signal } from '@angular/core';
|
|
2
|
+
import { MoltenDb } from '@moltendb-web/core';
|
|
3
|
+
import { MoltenDbClient } from '@moltendb-web/query';
|
|
4
|
+
import { MOLTEN_CONFIG } from './moltendb.provider';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
export class MoltenDbService {
|
|
7
|
+
db;
|
|
8
|
+
client;
|
|
9
|
+
// A Signal components can watch to know when WASM is booted and Leader Election is done
|
|
10
|
+
isReady = signal(false);
|
|
11
|
+
constructor() {
|
|
12
|
+
// 🚀 Modern Angular Injection (No constructor decorators needed!)
|
|
13
|
+
const config = inject(MOLTEN_CONFIG);
|
|
14
|
+
this.db = new MoltenDb(config.name, config);
|
|
15
|
+
this.client = new MoltenDbClient(this.db);
|
|
16
|
+
// Boot the engine and update the signal when done
|
|
17
|
+
this.db.init().then(() => {
|
|
18
|
+
this.isReady.set(true);
|
|
19
|
+
}).catch(err => {
|
|
20
|
+
console.error('[MoltenDb] Failed to initialize', err);
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MoltenDbService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
24
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MoltenDbService, providedIn: 'root' });
|
|
25
|
+
}
|
|
26
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MoltenDbService, decorators: [{
|
|
27
|
+
type: Injectable,
|
|
28
|
+
args: [{ providedIn: 'root' }]
|
|
29
|
+
}], ctorParameters: () => [] });
|
|
30
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9sdGVuZGIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvbW9sdGVuZGIuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0QsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0scUJBQXFCLENBQUM7O0FBR3BELE1BQU0sT0FBTyxlQUFlO0lBQ25CLEVBQUUsQ0FBVztJQUNiLE1BQU0sQ0FBaUI7SUFFOUIsd0ZBQXdGO0lBQ2pGLE9BQU8sR0FBRyxNQUFNLENBQVUsS0FBSyxDQUFDLENBQUM7SUFFeEM7UUFDRSxrRUFBa0U7UUFDbEUsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBRXJDLElBQUksQ0FBQyxFQUFFLEdBQUcsSUFBSSxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztRQUM1QyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksY0FBYyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUUxQyxrREFBa0Q7UUFDbEQsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFO1lBQ3ZCLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3pCLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBRTtZQUNiLE9BQU8sQ0FBQyxLQUFLLENBQUMsaUNBQWlDLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDeEQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO3dHQXBCVSxlQUFlOzRHQUFmLGVBQWUsY0FERixNQUFNOzs0RkFDbkIsZUFBZTtrQkFEM0IsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBpbmplY3QsIHNpZ25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTW9sdGVuRGIgfSBmcm9tICdAbW9sdGVuZGItd2ViL2NvcmUnO1xuaW1wb3J0IHsgTW9sdGVuRGJDbGllbnQgfSBmcm9tICdAbW9sdGVuZGItd2ViL3F1ZXJ5JztcbmltcG9ydCB7IE1PTFRFTl9DT05GSUcgfSBmcm9tICcuL21vbHRlbmRiLnByb3ZpZGVyJztcblxuQEluamVjdGFibGUoeyBwcm92aWRlZEluOiAncm9vdCcgfSlcbmV4cG9ydCBjbGFzcyBNb2x0ZW5EYlNlcnZpY2Uge1xuICBwdWJsaWMgZGI6IE1vbHRlbkRiO1xuICBwdWJsaWMgY2xpZW50OiBNb2x0ZW5EYkNsaWVudDtcblxuICAvLyBBIFNpZ25hbCBjb21wb25lbnRzIGNhbiB3YXRjaCB0byBrbm93IHdoZW4gV0FTTSBpcyBib290ZWQgYW5kIExlYWRlciBFbGVjdGlvbiBpcyBkb25lXG4gIHB1YmxpYyBpc1JlYWR5ID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICAvLyDwn5qAIE1vZGVybiBBbmd1bGFyIEluamVjdGlvbiAoTm8gY29uc3RydWN0b3IgZGVjb3JhdG9ycyBuZWVkZWQhKVxuICAgIGNvbnN0IGNvbmZpZyA9IGluamVjdChNT0xURU5fQ09ORklHKTtcblxuICAgIHRoaXMuZGIgPSBuZXcgTW9sdGVuRGIoY29uZmlnLm5hbWUsIGNvbmZpZyk7XG4gICAgdGhpcy5jbGllbnQgPSBuZXcgTW9sdGVuRGJDbGllbnQodGhpcy5kYik7XG5cbiAgICAvLyBCb290IHRoZSBlbmdpbmUgYW5kIHVwZGF0ZSB0aGUgc2lnbmFsIHdoZW4gZG9uZVxuICAgIHRoaXMuZGIuaW5pdCgpLnRoZW4oKCkgPT4ge1xuICAgICAgdGhpcy5pc1JlYWR5LnNldCh0cnVlKTtcbiAgICB9KS5jYXRjaChlcnIgPT4ge1xuICAgICAgY29uc29sZS5lcnJvcignW01vbHRlbkRiXSBGYWlsZWQgdG8gaW5pdGlhbGl6ZScsIGVycik7XG4gICAgfSk7XG4gIH1cbn0iXX0=
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generated bundle index. Do not edit.
|
|
3
|
+
*/
|
|
4
|
+
export * from './public-api';
|
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9sdGVuZGItd2ViLWFuZ3VsYXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbW9sdGVuZGItd2ViLWFuZ3VsYXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSCxjQUFjLGNBQWMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogR2VuZXJhdGVkIGJ1bmRsZSBpbmRleC4gRG8gbm90IGVkaXQuXG4gKi9cblxuZXhwb3J0ICogZnJvbSAnLi9wdWJsaWMtYXBpJztcbiJdfQ==
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Public API Surface of @moltendb-web/angular
|
|
3
|
+
*/
|
|
4
|
+
export * from './lib/moltendb.provider';
|
|
5
|
+
export * from './lib/moltendb.resource';
|
|
6
|
+
export * from './lib/moltendb.client';
|
|
7
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9wdWJsaWMtYXBpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsY0FBYyx5QkFBeUIsQ0FBQztBQUN4QyxjQUFjLHlCQUF5QixDQUFDO0FBQ3hDLGNBQWMsdUJBQXVCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogUHVibGljIEFQSSBTdXJmYWNlIG9mIEBtb2x0ZW5kYi13ZWIvYW5ndWxhclxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vbGliL21vbHRlbmRiLnByb3ZpZGVyJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL21vbHRlbmRiLnJlc291cmNlJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL21vbHRlbmRiLmNsaWVudCc7Il19
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { InjectionToken, makeEnvironmentProviders, signal, inject, Injectable, untracked, effect } from '@angular/core';
|
|
3
|
+
import { MoltenDb } from '@moltendb-web/core';
|
|
4
|
+
import { MoltenDbClient } from '@moltendb-web/query';
|
|
5
|
+
|
|
6
|
+
const MOLTEN_CONFIG = new InjectionToken('MOLTEN_CONFIG');
|
|
7
|
+
function provideMoltenDb(config) {
|
|
8
|
+
return makeEnvironmentProviders([
|
|
9
|
+
{ provide: MOLTEN_CONFIG, useValue: config }
|
|
10
|
+
]);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
class MoltenDbService {
|
|
14
|
+
db;
|
|
15
|
+
client;
|
|
16
|
+
// A Signal components can watch to know when WASM is booted and Leader Election is done
|
|
17
|
+
isReady = signal(false);
|
|
18
|
+
constructor() {
|
|
19
|
+
// 🚀 Modern Angular Injection (No constructor decorators needed!)
|
|
20
|
+
const config = inject(MOLTEN_CONFIG);
|
|
21
|
+
this.db = new MoltenDb(config.name, config);
|
|
22
|
+
this.client = new MoltenDbClient(this.db);
|
|
23
|
+
// Boot the engine and update the signal when done
|
|
24
|
+
this.db.init().then(() => {
|
|
25
|
+
this.isReady.set(true);
|
|
26
|
+
}).catch(err => {
|
|
27
|
+
console.error('[MoltenDb] Failed to initialize', err);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MoltenDbService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
31
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MoltenDbService, providedIn: 'root' });
|
|
32
|
+
}
|
|
33
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MoltenDbService, decorators: [{
|
|
34
|
+
type: Injectable,
|
|
35
|
+
args: [{ providedIn: 'root' }]
|
|
36
|
+
}], ctorParameters: () => [] });
|
|
37
|
+
|
|
38
|
+
function moltenDbResource(collection,
|
|
39
|
+
// Automatically infer the return type of .collection()
|
|
40
|
+
queryFn) {
|
|
41
|
+
const molten = inject(MoltenDbService);
|
|
42
|
+
const value = signal(undefined);
|
|
43
|
+
const isLoading = signal(false);
|
|
44
|
+
const error = signal(null);
|
|
45
|
+
const fetchData = async () => {
|
|
46
|
+
untracked(() => isLoading.set(true));
|
|
47
|
+
try {
|
|
48
|
+
// ⚡ Pre-bind the collection and pass it in!
|
|
49
|
+
const result = await queryFn(molten.client.collection(collection), molten.client);
|
|
50
|
+
value.set(result);
|
|
51
|
+
error.set(null);
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
if (err.message?.includes('404')) {
|
|
55
|
+
value.set([]);
|
|
56
|
+
error.set(null);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
error.set(err);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
finally {
|
|
63
|
+
isLoading.set(false);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
effect((onCleanup) => {
|
|
67
|
+
if (!molten.isReady())
|
|
68
|
+
return;
|
|
69
|
+
fetchData();
|
|
70
|
+
const unsubscribe = molten.db.subscribe((evt) => {
|
|
71
|
+
if (evt.collection === collection)
|
|
72
|
+
fetchData();
|
|
73
|
+
});
|
|
74
|
+
onCleanup(() => unsubscribe());
|
|
75
|
+
});
|
|
76
|
+
return {
|
|
77
|
+
value: value.asReadonly(),
|
|
78
|
+
isLoading: isLoading.asReadonly(),
|
|
79
|
+
error: error.asReadonly()
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Functional injection hook to access the MoltenDb Query Client.
|
|
85
|
+
* Removes the need to manually inject MoltenDbService in components.
|
|
86
|
+
*/
|
|
87
|
+
function moltendbClient() {
|
|
88
|
+
return inject(MoltenDbService).client;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/*
|
|
92
|
+
* Public API Surface of @moltendb-web/angular
|
|
93
|
+
*/
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Generated bundle index. Do not edit.
|
|
97
|
+
*/
|
|
98
|
+
|
|
99
|
+
export { MOLTEN_CONFIG, moltenDbResource, moltendbClient, provideMoltenDb };
|
|
100
|
+
//# sourceMappingURL=moltendb-web-angular.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"moltendb-web-angular.mjs","sources":["../../../src/lib/moltendb.provider.ts","../../../src/lib/moltendb.service.ts","../../../src/lib/moltendb.resource.ts","../../../src/lib/moltendb.client.ts","../../../src/public-api.ts","../../../src/moltendb-web-angular.ts"],"sourcesContent":["import { EnvironmentProviders, InjectionToken, makeEnvironmentProviders } from '@angular/core';\nimport { MoltenDbOptions } from '@moltendb-web/core';\n\nexport interface AngularMoltenDbOptions extends MoltenDbOptions {\n name: string;\n}\n\nexport const MOLTEN_CONFIG = new InjectionToken<AngularMoltenDbOptions>('MOLTEN_CONFIG');\n\nexport function provideMoltenDb(config: AngularMoltenDbOptions): EnvironmentProviders {\n return makeEnvironmentProviders([\n { provide: MOLTEN_CONFIG, useValue: config }\n ]);\n}","import { Injectable, inject, signal } from '@angular/core';\nimport { MoltenDb } from '@moltendb-web/core';\nimport { MoltenDbClient } from '@moltendb-web/query';\nimport { MOLTEN_CONFIG } from './moltendb.provider';\n\n@Injectable({ providedIn: 'root' })\nexport class MoltenDbService {\n public db: MoltenDb;\n public client: MoltenDbClient;\n\n // A Signal components can watch to know when WASM is booted and Leader Election is done\n public isReady = signal<boolean>(false);\n\n constructor() {\n // 🚀 Modern Angular Injection (No constructor decorators needed!)\n const config = inject(MOLTEN_CONFIG);\n\n this.db = new MoltenDb(config.name, config);\n this.client = new MoltenDbClient(this.db);\n\n // Boot the engine and update the signal when done\n this.db.init().then(() => {\n this.isReady.set(true);\n }).catch(err => {\n console.error('[MoltenDb] Failed to initialize', err);\n });\n }\n}","import { inject, signal, effect, Signal, untracked } from '@angular/core';\nimport { MoltenDbClient } from '@moltendb-web/query';\nimport { MoltenDbService } from './moltendb.service';\n\nexport interface MoltenDbResource<T> {\n value: Signal<T | undefined>;\n isLoading: Signal<boolean>;\n error: Signal<any | null>;\n}\n\nexport function moltenDbResource<T>(\n collection: string,\n // Automatically infer the return type of .collection()\n queryFn: (collection: ReturnType<MoltenDbClient['collection']>, client: MoltenDbClient) => Promise<T>\n): MoltenDbResource<T> {\n const molten = inject(MoltenDbService);\n\n const value = signal<T | undefined>(undefined);\n const isLoading = signal<boolean>(false);\n const error = signal<any | null>(null);\n\n const fetchData = async () => {\n untracked(() => isLoading.set(true));\n\n try {\n // ⚡ Pre-bind the collection and pass it in!\n const result = await queryFn(molten.client.collection(collection), molten.client);\n value.set(result);\n error.set(null);\n } catch (err: any) {\n if (err.message?.includes('404')) {\n value.set([] as any);\n error.set(null);\n } else {\n error.set(err);\n }\n } finally {\n isLoading.set(false);\n }\n };\n\n effect((onCleanup) => {\n if (!molten.isReady()) return;\n\n fetchData();\n\n const unsubscribe = molten.db.subscribe((evt) => {\n if (evt.collection === collection) fetchData();\n });\n\n onCleanup(() => unsubscribe());\n });\n\n return {\n value: value.asReadonly(),\n isLoading: isLoading.asReadonly(),\n error: error.asReadonly()\n };\n}","import { inject } from '@angular/core';\nimport { MoltenDbClient } from '@moltendb-web/query';\nimport { MoltenDbService } from './moltendb.service';\n\n/**\n * Functional injection hook to access the MoltenDb Query Client.\n * Removes the need to manually inject MoltenDbService in components.\n */\nexport function moltendbClient(): MoltenDbClient {\n return inject(MoltenDbService).client;\n}","/*\n * Public API Surface of @moltendb-web/angular\n */\n\nexport * from './lib/moltendb.provider';\nexport * from './lib/moltendb.resource';\nexport * from './lib/moltendb.client';","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { EnvironmentProviders, InjectionToken } from '@angular/core';
|
|
2
|
+
import { MoltenDbOptions } from '@moltendb-web/core';
|
|
3
|
+
export interface AngularMoltenDbOptions extends MoltenDbOptions {
|
|
4
|
+
name: string;
|
|
5
|
+
}
|
|
6
|
+
export declare const MOLTEN_CONFIG: InjectionToken<AngularMoltenDbOptions>;
|
|
7
|
+
export declare function provideMoltenDb(config: AngularMoltenDbOptions): EnvironmentProviders;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Signal } from '@angular/core';
|
|
2
|
+
import { MoltenDbClient } from '@moltendb-web/query';
|
|
3
|
+
export interface MoltenDbResource<T> {
|
|
4
|
+
value: Signal<T | undefined>;
|
|
5
|
+
isLoading: Signal<boolean>;
|
|
6
|
+
error: Signal<any | null>;
|
|
7
|
+
}
|
|
8
|
+
export declare function moltenDbResource<T>(collection: string, queryFn: (collection: ReturnType<MoltenDbClient['collection']>, client: MoltenDbClient) => Promise<T>): MoltenDbResource<T>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { MoltenDb } from '@moltendb-web/core';
|
|
2
|
+
import { MoltenDbClient } from '@moltendb-web/query';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
export declare class MoltenDbService {
|
|
5
|
+
db: MoltenDb;
|
|
6
|
+
client: MoltenDbClient;
|
|
7
|
+
isReady: import("@angular/core").WritableSignal<boolean>;
|
|
8
|
+
constructor();
|
|
9
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MoltenDbService, never>;
|
|
10
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<MoltenDbService>;
|
|
11
|
+
}
|
package/ng-package.json
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@moltendb-web/angular",
|
|
3
|
+
"version": "1.0.0-rc.5",
|
|
4
|
+
"description": "Official Angular Signals wrapper for MoltenDb",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"author": "Maximilian Both <maximilian.both27@outlook.com>",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "ng-packagr -p ng-package.json",
|
|
10
|
+
"dev": "ng-packagr -p ng-package.json --watch",
|
|
11
|
+
"prepublishOnly": "npm run build"
|
|
12
|
+
},
|
|
13
|
+
"peerDependencies": {
|
|
14
|
+
"@angular/core": ">=16.0.0",
|
|
15
|
+
"@moltendb-web/core": "^1.0.0-rc.5",
|
|
16
|
+
"@moltendb-web/query": "^1.0.0-rc.4"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@angular/compiler": "^17.0.0",
|
|
20
|
+
"@angular/compiler-cli": "^17.0.0",
|
|
21
|
+
"@angular/core": "^17.0.0",
|
|
22
|
+
"@moltendb-web/core": "^1.0.0-rc.5",
|
|
23
|
+
"@moltendb-web/query": "^1.0.0-rc.4",
|
|
24
|
+
"ng-packagr": "^17.0.0",
|
|
25
|
+
"typescript": "^5.2.2",
|
|
26
|
+
"tslib": "^2.3.0"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { inject } from '@angular/core';
|
|
2
|
+
import { MoltenDbClient } from '@moltendb-web/query';
|
|
3
|
+
import { MoltenDbService } from './moltendb.service';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Functional injection hook to access the MoltenDb Query Client.
|
|
7
|
+
* Removes the need to manually inject MoltenDbService in components.
|
|
8
|
+
*/
|
|
9
|
+
export function moltendbClient(): MoltenDbClient {
|
|
10
|
+
return inject(MoltenDbService).client;
|
|
11
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { EnvironmentProviders, InjectionToken, makeEnvironmentProviders } from '@angular/core';
|
|
2
|
+
import { MoltenDbOptions } from '@moltendb-web/core';
|
|
3
|
+
|
|
4
|
+
export interface AngularMoltenDbOptions extends MoltenDbOptions {
|
|
5
|
+
name: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const MOLTEN_CONFIG = new InjectionToken<AngularMoltenDbOptions>('MOLTEN_CONFIG');
|
|
9
|
+
|
|
10
|
+
export function provideMoltenDb(config: AngularMoltenDbOptions): EnvironmentProviders {
|
|
11
|
+
return makeEnvironmentProviders([
|
|
12
|
+
{ provide: MOLTEN_CONFIG, useValue: config }
|
|
13
|
+
]);
|
|
14
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { inject, signal, effect, Signal, untracked } from '@angular/core';
|
|
2
|
+
import { MoltenDbClient } from '@moltendb-web/query';
|
|
3
|
+
import { MoltenDbService } from './moltendb.service';
|
|
4
|
+
|
|
5
|
+
export interface MoltenDbResource<T> {
|
|
6
|
+
value: Signal<T | undefined>;
|
|
7
|
+
isLoading: Signal<boolean>;
|
|
8
|
+
error: Signal<any | null>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function moltenDbResource<T>(
|
|
12
|
+
collection: string,
|
|
13
|
+
// Automatically infer the return type of .collection()
|
|
14
|
+
queryFn: (collection: ReturnType<MoltenDbClient['collection']>, client: MoltenDbClient) => Promise<T>
|
|
15
|
+
): MoltenDbResource<T> {
|
|
16
|
+
const molten = inject(MoltenDbService);
|
|
17
|
+
|
|
18
|
+
const value = signal<T | undefined>(undefined);
|
|
19
|
+
const isLoading = signal<boolean>(false);
|
|
20
|
+
const error = signal<any | null>(null);
|
|
21
|
+
|
|
22
|
+
const fetchData = async () => {
|
|
23
|
+
untracked(() => isLoading.set(true));
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
// ⚡ Pre-bind the collection and pass it in!
|
|
27
|
+
const result = await queryFn(molten.client.collection(collection), molten.client);
|
|
28
|
+
value.set(result);
|
|
29
|
+
error.set(null);
|
|
30
|
+
} catch (err: any) {
|
|
31
|
+
if (err.message?.includes('404')) {
|
|
32
|
+
value.set([] as any);
|
|
33
|
+
error.set(null);
|
|
34
|
+
} else {
|
|
35
|
+
error.set(err);
|
|
36
|
+
}
|
|
37
|
+
} finally {
|
|
38
|
+
isLoading.set(false);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
effect((onCleanup) => {
|
|
43
|
+
if (!molten.isReady()) return;
|
|
44
|
+
|
|
45
|
+
fetchData();
|
|
46
|
+
|
|
47
|
+
const unsubscribe = molten.db.subscribe((evt) => {
|
|
48
|
+
if (evt.collection === collection) fetchData();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
onCleanup(() => unsubscribe());
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
value: value.asReadonly(),
|
|
56
|
+
isLoading: isLoading.asReadonly(),
|
|
57
|
+
error: error.asReadonly()
|
|
58
|
+
};
|
|
59
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Injectable, inject, signal } from '@angular/core';
|
|
2
|
+
import { MoltenDb } from '@moltendb-web/core';
|
|
3
|
+
import { MoltenDbClient } from '@moltendb-web/query';
|
|
4
|
+
import { MOLTEN_CONFIG } from './moltendb.provider';
|
|
5
|
+
|
|
6
|
+
@Injectable({ providedIn: 'root' })
|
|
7
|
+
export class MoltenDbService {
|
|
8
|
+
public db: MoltenDb;
|
|
9
|
+
public client: MoltenDbClient;
|
|
10
|
+
|
|
11
|
+
// A Signal components can watch to know when WASM is booted and Leader Election is done
|
|
12
|
+
public isReady = signal<boolean>(false);
|
|
13
|
+
|
|
14
|
+
constructor() {
|
|
15
|
+
// 🚀 Modern Angular Injection (No constructor decorators needed!)
|
|
16
|
+
const config = inject(MOLTEN_CONFIG);
|
|
17
|
+
|
|
18
|
+
this.db = new MoltenDb(config.name, config);
|
|
19
|
+
this.client = new MoltenDbClient(this.db);
|
|
20
|
+
|
|
21
|
+
// Boot the engine and update the signal when done
|
|
22
|
+
this.db.init().then(() => {
|
|
23
|
+
this.isReady.set(true);
|
|
24
|
+
}).catch(err => {
|
|
25
|
+
console.error('[MoltenDb] Failed to initialize', err);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ES2022",
|
|
5
|
+
"moduleResolution": "node",
|
|
6
|
+
"lib": ["ES2022", "DOM"],
|
|
7
|
+
"strict": true,
|
|
8
|
+
"esModuleInterop": true,
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
"forceConsistentCasingInFileNames": true,
|
|
11
|
+
"experimentalDecorators": true,
|
|
12
|
+
"declaration": true,
|
|
13
|
+
"baseUrl": ".",
|
|
14
|
+
"paths": {
|
|
15
|
+
"@moltendb-web/core": ["../core/src/index.ts"],
|
|
16
|
+
"@moltendb-web/query": ["../query/src/index.ts"]
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"include": ["src/**/*.ts"],
|
|
20
|
+
"exclude": ["node_modules", "dist"]
|
|
21
|
+
}
|