entropic-bond 1.59.4 → 1.60.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +208 -4
- package/lib/entropic-bond.js +125 -61
- package/lib/entropic-bond.js.map +1 -1
- package/lib/entropic-bond.umd.cjs +2 -2
- package/lib/entropic-bond.umd.cjs.map +1 -1
- package/package.json +13 -12
- package/lib/auth/auth-mock.d.ts +0 -22
- package/lib/auth/auth.d.ts +0 -131
- package/lib/auth/user-auth-types.d.ts +0 -22
- package/lib/cloud-functions/cloud-functions-mock.d.ts +0 -11
- package/lib/cloud-functions/cloud-functions.d.ts +0 -19
- package/lib/cloud-storage/cloud-storage.d.ts +0 -24
- package/lib/cloud-storage/mock-cloud-storage.d.ts +0 -20
- package/lib/cloud-storage/stored-file.d.ts +0 -39
- package/lib/index.d.ts +0 -19
- package/lib/observable/observable.d.ts +0 -52
- package/lib/persistent/entropic-component.d.ts +0 -76
- package/lib/persistent/persistent.d.ts +0 -369
- package/lib/server-auth/server-auth-mock.d.ts +0 -12
- package/lib/server-auth/server-auth.d.ts +0 -24
- package/lib/store/cached-props-updater.d.ts +0 -67
- package/lib/store/data-source.d.ts +0 -158
- package/lib/store/json-data-source.d.ts +0 -77
- package/lib/store/mocks/test-user.d.ts +0 -54
- package/lib/store/model.d.ts +0 -244
- package/lib/store/store.d.ts +0 -62
- package/lib/types/utility-types.d.ts +0 -45
- package/lib/utils/test-utils/test-person.d.ts +0 -33
- package/lib/utils/utils.d.ts +0 -60
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ Typically, you will derive all your business logic entities from the `EntropicCo
|
|
|
19
19
|
|
|
20
20
|
### API
|
|
21
21
|
|
|
22
|
-
You can find the API documentation [
|
|
22
|
+
You can find the API documentation in the [docs/](./docs) directory.
|
|
23
23
|
|
|
24
24
|
### Persistence
|
|
25
25
|
|
|
@@ -31,7 +31,7 @@ The properties or attributes that you want to be streamed should be preceded by
|
|
|
31
31
|
|
|
32
32
|
```ts
|
|
33
33
|
@registerPersistentClass( 'MyEntity' )
|
|
34
|
-
class MyEntity extends
|
|
34
|
+
class MyEntity extends Persistent {
|
|
35
35
|
@persistent private _persistentProp1: string
|
|
36
36
|
@persistent private _persistentProp2: boolean
|
|
37
37
|
@persistent private _persistentProp3: AnotherPersistentObject
|
|
@@ -45,7 +45,7 @@ class MyEntity extends EntropicBond {
|
|
|
45
45
|
|
|
46
46
|
#### Storing and querying the persistent entities
|
|
47
47
|
|
|
48
|
-
The database abstraction is provided by the `Store` object.
|
|
48
|
+
The database abstraction is provided by the `Store` object.
|
|
49
49
|
|
|
50
50
|
The `Store.getModel` method will return an object with methods to access the database.
|
|
51
51
|
|
|
@@ -80,7 +80,7 @@ Currently, there is an official plugin to connect to a **Firebase** _Firestore_
|
|
|
80
80
|
npm i entropic-bond-firebase
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
-
You can develop new plugins following the
|
|
83
|
+
You can develop new plugins following the plugin developer's section.
|
|
84
84
|
|
|
85
85
|
You should instantiate the concrete implementation of the `DataSource` and pass it to the `useDataSource` method of the `Store` object.
|
|
86
86
|
|
|
@@ -88,10 +88,214 @@ You should instantiate the concrete implementation of the `DataSource` and pass
|
|
|
88
88
|
Store.useDataSource( new JsonDataSource() )
|
|
89
89
|
```
|
|
90
90
|
|
|
91
|
+
> See the complete example at [samples/01-persistence.ts](./samples/01-persistence.ts)
|
|
92
|
+
|
|
91
93
|
### Observability
|
|
92
94
|
|
|
95
|
+
The observability mechanism allows entities to notify when their properties change. Derive your class from `EntropicComponent` (which extends `Persistent`) and use `changeProp` in setters or `pushAndNotify`/`removeAndNotify` for arrays.
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
import { EntropicComponent } from 'entropic-bond'
|
|
99
|
+
|
|
100
|
+
class MyEntity extends EntropicComponent {
|
|
101
|
+
private _name: string = ''
|
|
102
|
+
|
|
103
|
+
get name(): string { return this._name }
|
|
104
|
+
set name(value: string) { this.changeProp('name', value) }
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const entity = new MyEntity()
|
|
108
|
+
const unsub = entity.onChange(event => console.log('Changed:', event))
|
|
109
|
+
|
|
110
|
+
entity.name = 'new value' // triggers the onChange listener
|
|
111
|
+
unsub() // removes the listener
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
You can also directly use the generic `Observable<T>` class for standalone observer patterns.
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
import { Observable } from 'entropic-bond'
|
|
118
|
+
|
|
119
|
+
const observable = new Observable<string>()
|
|
120
|
+
const unsubscribe = observable.subscribe(event => console.log(event))
|
|
121
|
+
observable.notify('hello')
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
> See the complete example at [samples/02-observability.ts](./samples/02-observability.ts)
|
|
125
|
+
|
|
93
126
|
### Auth
|
|
94
127
|
|
|
128
|
+
Authentication is abstracted via `AuthService`. Register a concrete implementation and use the `Auth` singleton.
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
import { Auth, AuthMock } from 'entropic-bond'
|
|
132
|
+
|
|
133
|
+
Auth.useAuthService(new AuthMock())
|
|
134
|
+
|
|
135
|
+
async function example() {
|
|
136
|
+
const user = await Auth.instance.login({ authProvider: 'email', email: 'user@test.com', password: '123456' })
|
|
137
|
+
console.log(user.id, user.email)
|
|
138
|
+
|
|
139
|
+
Auth.instance.onAuthStateChange(credentials => {
|
|
140
|
+
console.log('Auth state changed:', credentials)
|
|
141
|
+
})
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Plugins exist for production providers (e.g., Firebase Authentication). To create a custom provider, implement the `AuthService` abstract class.
|
|
146
|
+
|
|
147
|
+
> See the complete example at [samples/03-auth.ts](./samples/03-auth.ts)
|
|
148
|
+
|
|
149
|
+
### Server Auth
|
|
150
|
+
|
|
151
|
+
For admin-level user management (list, update, delete users), use `ServerAuth`.
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
import { ServerAuth, ServerAuthMock } from 'entropic-bond'
|
|
155
|
+
|
|
156
|
+
ServerAuth.useServerAuthService(new ServerAuthMock())
|
|
157
|
+
|
|
158
|
+
const user = await ServerAuth.instance.getUser('user-id')
|
|
159
|
+
await ServerAuth.instance.updateUser('user-id', { name: 'Updated Name' })
|
|
160
|
+
await ServerAuth.instance.deleteUser('user-id')
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
> See the complete example at [samples/04-server-auth.ts](./samples/04-server-auth.ts)
|
|
164
|
+
|
|
165
|
+
### Cloud Storage
|
|
166
|
+
|
|
167
|
+
File storage is abstracted via `CloudStorage`. Register a provider and use the singleton, or use the `StoredFile` persistent entity.
|
|
168
|
+
|
|
169
|
+
```ts
|
|
170
|
+
import { CloudStorage, MockCloudStorage, StoredFile } from 'entropic-bond'
|
|
171
|
+
|
|
172
|
+
CloudStorage.useCloudStorage(new MockCloudStorage())
|
|
173
|
+
|
|
174
|
+
// Direct usage
|
|
175
|
+
const url = await CloudStorage.defaultCloudStorage.save('my-file', fileData)
|
|
176
|
+
const downloadUrl = await CloudStorage.defaultCloudStorage.getUrl('my-file')
|
|
177
|
+
|
|
178
|
+
// Or with StoredFile (persistent entity)
|
|
179
|
+
const file = new StoredFile()
|
|
180
|
+
file.setDataToStore(someBlob)
|
|
181
|
+
await file.save()
|
|
182
|
+
console.log(file.url)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
> See the complete example at [samples/05-cloud-storage.ts](./samples/05-cloud-storage.ts)
|
|
186
|
+
|
|
187
|
+
### Cloud Functions
|
|
188
|
+
|
|
189
|
+
Call serverless functions through an abstract interface.
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
import { CloudFunctions, CloudFunctionsMock } from 'entropic-bond'
|
|
193
|
+
|
|
194
|
+
const mockService = new CloudFunctionsMock({
|
|
195
|
+
myFunction: async (params) => `Hello ${params.name}`
|
|
196
|
+
})
|
|
197
|
+
CloudFunctions.useCloudFunctionsService(mockService)
|
|
198
|
+
|
|
199
|
+
const fn = CloudFunctions.instance.getFunction('myFunction')
|
|
200
|
+
const result = await fn({ name: 'World' })
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
> See the complete example at [samples/06-cloud-functions.ts](./samples/06-cloud-functions.ts)
|
|
204
|
+
|
|
205
|
+
### Realtime document listeners
|
|
206
|
+
|
|
207
|
+
The `Model` supports realtime updates on documents and collections.
|
|
208
|
+
|
|
209
|
+
```ts
|
|
210
|
+
const model = Store.getModel<MyEntity>('MyEntity')
|
|
211
|
+
|
|
212
|
+
// Listen to a single document
|
|
213
|
+
const unsubscribe1 = model.onDocumentChange('doc-id', change => {
|
|
214
|
+
console.log('Before:', change.before, 'After:', change.after)
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
// Listen to a collection query
|
|
218
|
+
const unsubscribe2 = model.onCollectionChange(
|
|
219
|
+
model.find().where('name', '==', 'foo'),
|
|
220
|
+
change => console.log('Collection changed:', change)
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
// Listen to a wildcard collection template
|
|
224
|
+
const unsubscribe3 = model.onCollectionTemplateChange('{userId}/Posts', change => {
|
|
225
|
+
console.log('Post changed in', change.collectionPath)
|
|
226
|
+
})
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
> See the complete example at [samples/07-realtime-listeners.ts](./samples/07-realtime-listeners.ts)
|
|
230
|
+
|
|
231
|
+
### DataSource plugins
|
|
232
|
+
|
|
233
|
+
The persistence layer uses a `DataSource` to communicate with the database. Implement the abstract `DataSource` class to support new backends.
|
|
234
|
+
|
|
235
|
+
```ts
|
|
236
|
+
import { DataSource, Store } from 'entropic-bond'
|
|
237
|
+
|
|
238
|
+
class MyDatabase extends DataSource {
|
|
239
|
+
// implement all abstract methods: findById, find, save, delete, etc.
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
Store.useDataSource(new MyDatabase())
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
The official Firebase plugin is available as `entropic-bond-firebase`.
|
|
246
|
+
|
|
247
|
+
```sh
|
|
248
|
+
npm i entropic-bond-firebase
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
> See the complete example at [samples/10-datasource-plugin.ts](./samples/10-datasource-plugin.ts)
|
|
252
|
+
|
|
253
|
+
### Cached property references
|
|
254
|
+
|
|
255
|
+
When a property holds a reference to another persistent entity, you can embed selected primitive fields directly in the reference to avoid extra queries.
|
|
256
|
+
|
|
257
|
+
```ts
|
|
258
|
+
@registerPersistentClass('Team')
|
|
259
|
+
class Team extends EntropicComponent {
|
|
260
|
+
@persistent private _name: string
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
@registerPersistentClass('User')
|
|
264
|
+
class User extends EntropicComponent {
|
|
265
|
+
@persistentReferenceWithCachedProps(['_name'], 'Team')
|
|
266
|
+
private _team: Team
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
The `CachedPropsUpdater` (installed via `DataSource.installCachedPropsUpdater()`) will propagate changes to cached props across all referencing documents.
|
|
271
|
+
|
|
272
|
+
> See the complete example at [samples/08-cached-props.ts](./samples/08-cached-props.ts)
|
|
273
|
+
|
|
274
|
+
### Utility functions
|
|
275
|
+
|
|
276
|
+
```ts
|
|
277
|
+
import { camelCase, snakeCase, replaceValue, getDeepValue } from 'entropic-bond'
|
|
278
|
+
|
|
279
|
+
camelCase('hello-world') // 'helloWorld'
|
|
280
|
+
snakeCase('helloWorld') // 'hello-world'
|
|
281
|
+
replaceValue('Hi ${name}', { name: 'John' }) // 'Hi John'
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
> See the complete example at [samples/09-utils.ts](./samples/09-utils.ts)
|
|
95
285
|
|
|
286
|
+
### Samples
|
|
96
287
|
|
|
288
|
+
Complete, runnable examples are available in the [`samples/`](./samples) directory:
|
|
97
289
|
|
|
290
|
+
| Section | Sample |
|
|
291
|
+
|---------|--------|
|
|
292
|
+
| Persistence | [01-persistence.ts](./samples/01-persistence.ts) |
|
|
293
|
+
| Observability | [02-observability.ts](./samples/02-observability.ts) |
|
|
294
|
+
| Auth | [03-auth.ts](./samples/03-auth.ts) |
|
|
295
|
+
| Server Auth | [04-server-auth.ts](./samples/04-server-auth.ts) |
|
|
296
|
+
| Cloud Storage | [05-cloud-storage.ts](./samples/05-cloud-storage.ts) |
|
|
297
|
+
| Cloud Functions | [06-cloud-functions.ts](./samples/06-cloud-functions.ts) |
|
|
298
|
+
| Realtime listeners | [07-realtime-listeners.ts](./samples/07-realtime-listeners.ts) |
|
|
299
|
+
| Cached property references | [08-cached-props.ts](./samples/08-cached-props.ts) |
|
|
300
|
+
| Utility functions | [09-utils.ts](./samples/09-utils.ts) |
|
|
301
|
+
| DataSource plugins | [10-datasource-plugin.ts](./samples/10-datasource-plugin.ts) |
|