tinybase 3.0.0 → 3.0.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/lib/cjs/checkpoints.cjs +1 -0
- package/lib/cjs/checkpoints.cjs.gz +0 -0
- package/lib/cjs/checkpoints.d.ts +959 -0
- package/lib/cjs/common.cjs +1 -0
- package/lib/cjs/common.cjs.gz +0 -0
- package/lib/cjs/common.d.ts +115 -0
- package/lib/cjs/indexes.cjs +1 -0
- package/lib/cjs/indexes.cjs.gz +0 -0
- package/lib/cjs/indexes.d.ts +966 -0
- package/lib/cjs/metrics.cjs +1 -0
- package/lib/cjs/metrics.cjs.gz +0 -0
- package/lib/cjs/metrics.d.ts +827 -0
- package/lib/cjs/persisters.cjs +1 -0
- package/lib/cjs/persisters.cjs.gz +0 -0
- package/lib/cjs/persisters.d.ts +727 -0
- package/lib/cjs/queries.cjs +1 -0
- package/lib/cjs/queries.cjs.gz +0 -0
- package/lib/cjs/queries.d.ts +3024 -0
- package/lib/cjs/relationships.cjs +1 -0
- package/lib/cjs/relationships.cjs.gz +0 -0
- package/lib/cjs/relationships.d.ts +1201 -0
- package/lib/cjs/store.cjs +1 -0
- package/lib/cjs/store.cjs.gz +0 -0
- package/lib/cjs/store.d.ts +5244 -0
- package/lib/cjs/tinybase.cjs +1 -0
- package/lib/cjs/tinybase.cjs.gz +0 -0
- package/lib/cjs/tinybase.d.ts +14 -0
- package/lib/cjs/tools.cjs +1 -0
- package/lib/cjs/tools.cjs.gz +0 -0
- package/lib/cjs/tools.d.ts +512 -0
- package/lib/cjs/ui-react.cjs +1 -0
- package/lib/cjs/ui-react.cjs.gz +0 -0
- package/lib/cjs/ui-react.d.ts +10921 -0
- package/lib/cjs-es6/checkpoints.cjs +1 -0
- package/lib/cjs-es6/checkpoints.cjs.gz +0 -0
- package/lib/cjs-es6/checkpoints.d.ts +959 -0
- package/lib/cjs-es6/common.cjs +1 -0
- package/lib/cjs-es6/common.cjs.gz +0 -0
- package/lib/cjs-es6/common.d.ts +115 -0
- package/lib/cjs-es6/indexes.cjs +1 -0
- package/lib/cjs-es6/indexes.cjs.gz +0 -0
- package/lib/cjs-es6/indexes.d.ts +966 -0
- package/lib/cjs-es6/metrics.cjs +1 -0
- package/lib/cjs-es6/metrics.cjs.gz +0 -0
- package/lib/cjs-es6/metrics.d.ts +827 -0
- package/lib/cjs-es6/persisters.cjs +1 -0
- package/lib/cjs-es6/persisters.cjs.gz +0 -0
- package/lib/cjs-es6/persisters.d.ts +727 -0
- package/lib/cjs-es6/queries.cjs +1 -0
- package/lib/cjs-es6/queries.cjs.gz +0 -0
- package/lib/cjs-es6/queries.d.ts +3024 -0
- package/lib/cjs-es6/relationships.cjs +1 -0
- package/lib/cjs-es6/relationships.cjs.gz +0 -0
- package/lib/cjs-es6/relationships.d.ts +1201 -0
- package/lib/cjs-es6/store.cjs +1 -0
- package/lib/cjs-es6/store.cjs.gz +0 -0
- package/lib/cjs-es6/store.d.ts +5244 -0
- package/lib/cjs-es6/tinybase.cjs +1 -0
- package/lib/cjs-es6/tinybase.cjs.gz +0 -0
- package/lib/cjs-es6/tinybase.d.ts +14 -0
- package/lib/cjs-es6/tools.cjs +1 -0
- package/lib/cjs-es6/tools.cjs.gz +0 -0
- package/lib/cjs-es6/tools.d.ts +512 -0
- package/lib/cjs-es6/ui-react.cjs +1 -0
- package/lib/cjs-es6/ui-react.cjs.gz +0 -0
- package/lib/cjs-es6/ui-react.d.ts +10921 -0
- package/lib/debug/tools.js +2 -1
- package/lib/es6/tools.js +1 -1
- package/lib/es6/tools.js.gz +0 -0
- package/lib/tools.js +1 -1
- package/lib/tools.js.gz +0 -0
- package/lib/umd/tools.js +1 -1
- package/lib/umd/tools.js.gz +0 -0
- package/lib/umd-es6/tools.js +1 -1
- package/lib/umd-es6/tools.js.gz +0 -0
- package/package.json +28 -20
- package/readme.md +1 -1
|
@@ -0,0 +1,1201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The relationships module of the TinyBase project provides the ability to
|
|
3
|
+
* create and track relationships between the data in Store objects.
|
|
4
|
+
*
|
|
5
|
+
* The main entry point to this module is the createRelationships function,
|
|
6
|
+
* which returns a new Relationships object. From there, you can create new
|
|
7
|
+
* Relationship definitions, access the associations within those Relationships
|
|
8
|
+
* directly, and register listeners for when they change.
|
|
9
|
+
*
|
|
10
|
+
* @packageDocumentation
|
|
11
|
+
* @module relationships
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import {GetCell, RowCallback, Store} from './store.d';
|
|
15
|
+
import {Id, IdOrNull, Ids} from './common.d';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The Relationship type represents the concept of a map that connects one Row
|
|
19
|
+
* object to another, often in another Table.
|
|
20
|
+
*
|
|
21
|
+
* The Relationship has a one-to-many nature. One local Row Id is linked to one
|
|
22
|
+
* remote Row Id (in the remote Table), as described by the
|
|
23
|
+
* setRelationshipDefinition method - and one remote Row Id may map back to
|
|
24
|
+
* multiple local Row Ids (in the local Table).
|
|
25
|
+
*
|
|
26
|
+
* A Relationship where the local Table is the same as the remote Table can be
|
|
27
|
+
* used to model a 'linked list', where Row A references Row B, Row B references
|
|
28
|
+
* Row C, and so on.
|
|
29
|
+
*
|
|
30
|
+
* Note that the Relationship type is not actually used in the API, and you
|
|
31
|
+
* instead enumerate and access its structure with the getRemoteRowId method,
|
|
32
|
+
* the getLocalRowIds method, and the getLinkedRowIds method.
|
|
33
|
+
*
|
|
34
|
+
* @category Concept
|
|
35
|
+
*/
|
|
36
|
+
export type Relationship = {
|
|
37
|
+
remoteRowId: {[localRowId: Id]: Id};
|
|
38
|
+
localRowIds: {[remoteRowId: Id]: Ids};
|
|
39
|
+
linkedRowIds: {[firstRowId: Id]: Ids};
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* The RelationshipCallback type describes a function that takes a
|
|
44
|
+
* Relationship's Id and a callback to loop over each local Row within it.
|
|
45
|
+
*
|
|
46
|
+
* A RelationshipCallback is provided when using the forEachRelationship method,
|
|
47
|
+
* so that you can do something based on every Relationship in the Relationships
|
|
48
|
+
* object. See that method for specific examples.
|
|
49
|
+
*
|
|
50
|
+
* @param relationshipId The Id of the Relationship that the callback can
|
|
51
|
+
* operate on.
|
|
52
|
+
* @param forEachRow A function that will let you iterate over the local Row
|
|
53
|
+
* objects in this Relationship.
|
|
54
|
+
* @category Callback
|
|
55
|
+
*/
|
|
56
|
+
export type RelationshipCallback = (
|
|
57
|
+
relationshipId: Id,
|
|
58
|
+
forEachRow: (rowCallback: RowCallback) => void,
|
|
59
|
+
) => void;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* The RemoteRowIdListener type describes a function that is used to listen to
|
|
63
|
+
* changes to the remote Row Id end of a Relationship.
|
|
64
|
+
*
|
|
65
|
+
* A RemoteRowIdListener is provided when using the addRemoteRowIdListener
|
|
66
|
+
* method. See that method for specific examples.
|
|
67
|
+
*
|
|
68
|
+
* When called, a RemoteRowIdListener is given a reference to the Relationships
|
|
69
|
+
* object, the Id of the Relationship that changed, and the Id of the local Row
|
|
70
|
+
* whose remote Row Id changed.
|
|
71
|
+
*
|
|
72
|
+
* @param relationships A reference to the Relationships object that changed.
|
|
73
|
+
* @param relationshipId The Id of the Relationship that changed.
|
|
74
|
+
* @param localRowId The Id of the local Row whose remote Row Id changed.
|
|
75
|
+
* @category Listener
|
|
76
|
+
*/
|
|
77
|
+
export type RemoteRowIdListener = (
|
|
78
|
+
relationships: Relationships,
|
|
79
|
+
relationshipId: Id,
|
|
80
|
+
localRowId: Id,
|
|
81
|
+
) => void;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* The LocalRowIdsListener type describes a function that is used to listen to
|
|
85
|
+
* changes to the local Row Id ends of a Relationship.
|
|
86
|
+
*
|
|
87
|
+
* A LocalRowIdsListener is provided when using the addLocalRowIdsListener
|
|
88
|
+
* method. See that method for specific examples.
|
|
89
|
+
*
|
|
90
|
+
* When called, a LocalRowIdsListener is given a reference to the Relationships
|
|
91
|
+
* object, the Id of the Relationship that changed, and the Id of the remote Row
|
|
92
|
+
* whose local Row Ids changed.
|
|
93
|
+
*
|
|
94
|
+
* @param relationships A reference to the Relationships object that changed.
|
|
95
|
+
* @param relationshipId The Id of the Relationship that changed.
|
|
96
|
+
* @param remoteRowId The Id of the remote Row whose local Row Ids changed.
|
|
97
|
+
* @category Listener
|
|
98
|
+
*/
|
|
99
|
+
export type LocalRowIdsListener = (
|
|
100
|
+
relationships: Relationships,
|
|
101
|
+
relationshipId: Id,
|
|
102
|
+
remoteRowId: Id,
|
|
103
|
+
) => void;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* The LinkedRowIdsListener type describes a function that is used to listen to
|
|
107
|
+
* changes to the local Row Id ends of a Relationship.
|
|
108
|
+
*
|
|
109
|
+
* A LinkedRowIdsListener is provided when using the addLinkedRowIdsListener
|
|
110
|
+
* method. See that method for specific examples.
|
|
111
|
+
*
|
|
112
|
+
* When called, a LinkedRowIdsListener is given a reference to the Relationships
|
|
113
|
+
* object, the Id of the Relationship that changed, and the Id of the first Row
|
|
114
|
+
* of the the linked list whose members changed.
|
|
115
|
+
*
|
|
116
|
+
* @param relationships A reference to the Relationships object that changed.
|
|
117
|
+
* @param relationshipId The Id of the Relationship that changed.
|
|
118
|
+
* @param firstRowId The Id of the first Row of the the linked list whose
|
|
119
|
+
* members changed.
|
|
120
|
+
* @category Listener
|
|
121
|
+
*/
|
|
122
|
+
export type LinkedRowIdsListener = (
|
|
123
|
+
relationships: Relationships,
|
|
124
|
+
relationshipId: Id,
|
|
125
|
+
firstRowId: Id,
|
|
126
|
+
) => void;
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* The RelationshipsListenerStats type describes the number of listeners
|
|
130
|
+
* registered with the Relationships object, and can be used for debugging
|
|
131
|
+
* purposes.
|
|
132
|
+
*
|
|
133
|
+
* A RelationshipsListenerStats object is returned from the getListenerStats
|
|
134
|
+
* method, and is only populated in a debug build.
|
|
135
|
+
*
|
|
136
|
+
* @category Development
|
|
137
|
+
*/
|
|
138
|
+
export type RelationshipsListenerStats = {
|
|
139
|
+
/**
|
|
140
|
+
* The number of RemoteRowIdListener functions registered with the
|
|
141
|
+
* Relationships object.
|
|
142
|
+
*/
|
|
143
|
+
remoteRowId?: number;
|
|
144
|
+
/**
|
|
145
|
+
* The number of LocalRowIdsListener functions registered with the
|
|
146
|
+
* Relationships object.
|
|
147
|
+
*/
|
|
148
|
+
localRowIds?: number;
|
|
149
|
+
/**
|
|
150
|
+
* The number of LinkedRowId functions registered with the Relationships
|
|
151
|
+
* object.
|
|
152
|
+
*/
|
|
153
|
+
linkedRowIds?: number;
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* A Relationships object lets you associate a Row in a one Table with the Id of
|
|
158
|
+
* a Row in another Table.
|
|
159
|
+
*
|
|
160
|
+
* This is useful for creating parent-child relationships between the data in
|
|
161
|
+
* different Table objects, but it can also be used to model a linked list of
|
|
162
|
+
* Row objects in the same Table.
|
|
163
|
+
*
|
|
164
|
+
* Create a Relationships object easily with the createRelationships function.
|
|
165
|
+
* From there, you can add new Relationship definitions (with the
|
|
166
|
+
* setRelationshipDefinition method), query their contents (with the
|
|
167
|
+
* getRemoteRowId method, the getLocalRowIds method, and the getLinkedRowIds
|
|
168
|
+
* method), and add listeners for when they change (with the
|
|
169
|
+
* addRemoteRowIdListener method, the addLocalRowIdsListener method, and the
|
|
170
|
+
* addLinkedRowIdsListener method).
|
|
171
|
+
*
|
|
172
|
+
* This module defaults to creating relationships between Row objects by using
|
|
173
|
+
* one of their Cell values. However, far more complex relationships can be
|
|
174
|
+
* configured with a custom function.
|
|
175
|
+
*
|
|
176
|
+
* @example
|
|
177
|
+
* This example shows a very simple lifecycle of a Relationships object: from
|
|
178
|
+
* creation, to adding definitions (both local/remote table and linked list),
|
|
179
|
+
* getting their contents, and then registering and removing listeners for them.
|
|
180
|
+
*
|
|
181
|
+
* ```js
|
|
182
|
+
* const store = createStore()
|
|
183
|
+
* .setTable('pets', {
|
|
184
|
+
* fido: {species: 'dog', next: 'felix'},
|
|
185
|
+
* felix: {species: 'cat', next: 'cujo'},
|
|
186
|
+
* cujo: {species: 'dog'},
|
|
187
|
+
* })
|
|
188
|
+
* .setTable('species', {
|
|
189
|
+
* dog: {price: 5},
|
|
190
|
+
* cat: {price: 4},
|
|
191
|
+
* });
|
|
192
|
+
*
|
|
193
|
+
* const relationships = createRelationships(store);
|
|
194
|
+
*
|
|
195
|
+
* // A local/remote table relationship:
|
|
196
|
+
* relationships.setRelationshipDefinition(
|
|
197
|
+
* 'petSpecies', // relationshipId
|
|
198
|
+
* 'pets', // localTableId to link from
|
|
199
|
+
* 'species', // remoteTableId to link to
|
|
200
|
+
* 'species', // cellId containing remote key
|
|
201
|
+
* );
|
|
202
|
+
* console.log(relationships.getRemoteRowId('petSpecies', 'fido'));
|
|
203
|
+
* // -> 'dog'
|
|
204
|
+
* console.log(relationships.getLocalRowIds('petSpecies', 'dog'));
|
|
205
|
+
* // -> ['fido', 'cujo']
|
|
206
|
+
*
|
|
207
|
+
* // A linked list relationship:
|
|
208
|
+
* relationships.setRelationshipDefinition(
|
|
209
|
+
* 'petSequence', // relationshipId
|
|
210
|
+
* 'pets', // localTableId to link from
|
|
211
|
+
* 'pets', // the same remoteTableId to link within
|
|
212
|
+
* 'next', // cellId containing link key
|
|
213
|
+
* );
|
|
214
|
+
* console.log(relationships.getLinkedRowIds('petSequence', 'fido'));
|
|
215
|
+
* // -> ['fido', 'felix', 'cujo']
|
|
216
|
+
*
|
|
217
|
+
* const listenerId1 = relationships.addLocalRowIdsListener(
|
|
218
|
+
* 'petSpecies',
|
|
219
|
+
* 'dog',
|
|
220
|
+
* () => {
|
|
221
|
+
* console.log('petSpecies relationship (to dog) changed');
|
|
222
|
+
* console.log(relationships.getLocalRowIds('petSpecies', 'dog'));
|
|
223
|
+
* },
|
|
224
|
+
* );
|
|
225
|
+
* const listenerId2 = relationships.addLinkedRowIdsListener(
|
|
226
|
+
* 'petSequence',
|
|
227
|
+
* 'fido',
|
|
228
|
+
* () => {
|
|
229
|
+
* console.log('petSequence linked list (from fido) changed');
|
|
230
|
+
* console.log(relationships.getLinkedRowIds('petSequence', 'fido'));
|
|
231
|
+
* },
|
|
232
|
+
* );
|
|
233
|
+
*
|
|
234
|
+
* store.setRow('pets', 'toto', {species: 'dog'});
|
|
235
|
+
* // -> 'petSpecies relationship (to dog) changed'
|
|
236
|
+
* // -> ['fido', 'cujo', 'toto']
|
|
237
|
+
*
|
|
238
|
+
* store.setCell('pets', 'cujo', 'next', 'toto');
|
|
239
|
+
* // -> 'petSequence linked list (from fido) changed'
|
|
240
|
+
* // -> ['fido', 'felix', 'cujo', 'toto']
|
|
241
|
+
*
|
|
242
|
+
* relationships.delListener(listenerId1);
|
|
243
|
+
* relationships.delListener(listenerId2);
|
|
244
|
+
* relationships.destroy();
|
|
245
|
+
* ```
|
|
246
|
+
* @see Relationships And Checkpoints guides
|
|
247
|
+
* @see Drawing demo
|
|
248
|
+
* @category Relationships
|
|
249
|
+
*/
|
|
250
|
+
export interface Relationships {
|
|
251
|
+
/**
|
|
252
|
+
* The setRelationshipDefinition method lets you set the definition of a
|
|
253
|
+
* Relationship.
|
|
254
|
+
*
|
|
255
|
+
* Every Relationship definition is identified by a unique Id, and if you
|
|
256
|
+
* re-use an existing Id with this method, the previous definition is
|
|
257
|
+
* overwritten.
|
|
258
|
+
*
|
|
259
|
+
* An Relationship is based on connections between Row objects, often in two
|
|
260
|
+
* different Table objects. Therefore the definition requires the
|
|
261
|
+
* `localTableId` parameter to specify the 'local' Table to create the
|
|
262
|
+
* Relationship from, and the `remoteTableId` parameter to specify the
|
|
263
|
+
* 'remote' Table to create Relationship to.
|
|
264
|
+
*
|
|
265
|
+
* A linked list Relationship is one that has the same Table specified as both
|
|
266
|
+
* local Table Id and remote Table Id, allowing you to create a sequence of
|
|
267
|
+
* Row objects within that one Table.
|
|
268
|
+
*
|
|
269
|
+
* A local Row is related to a remote Row by specifying which of its (local)
|
|
270
|
+
* Cell values contains the (remote) Row Id, using the `getRemoteRowId`
|
|
271
|
+
* parameter. Alternatively, a custom function can be provided that produces
|
|
272
|
+
* your own remote Row Id from the local Row as a whole.
|
|
273
|
+
*
|
|
274
|
+
* @param relationshipId The Id of the Relationship to define.
|
|
275
|
+
* @param localTableId The Id of the local Table for the Relationship.
|
|
276
|
+
* @param remoteTableId The Id of the remote Table for the Relationship (or
|
|
277
|
+
* the same as the `localTableId` in the case of a linked list).
|
|
278
|
+
* @param getRemoteRowId Either the Id of the Cell containing, or a function
|
|
279
|
+
* that produces, the Id that is used to indicate which Row in the remote
|
|
280
|
+
* Table a local Row is related to.
|
|
281
|
+
* @returns A reference to the Relationships object.
|
|
282
|
+
* @example
|
|
283
|
+
* This example creates a Store, creates a Relationships object, and defines
|
|
284
|
+
* a simple Relationship based on the values in the `species` Cell of the
|
|
285
|
+
* `pets` Table that relates a Row to another in the `species` Table.
|
|
286
|
+
*
|
|
287
|
+
* ```js
|
|
288
|
+
* const store = createStore()
|
|
289
|
+
* .setTable('pets', {
|
|
290
|
+
* fido: {species: 'dog'},
|
|
291
|
+
* felix: {species: 'cat'},
|
|
292
|
+
* cujo: {species: 'dog'},
|
|
293
|
+
* })
|
|
294
|
+
* .setTable('species', {
|
|
295
|
+
* dog: {price: 5},
|
|
296
|
+
* cat: {price: 4},
|
|
297
|
+
* });
|
|
298
|
+
*
|
|
299
|
+
* const relationships = createRelationships(store);
|
|
300
|
+
* relationships.setRelationshipDefinition(
|
|
301
|
+
* 'petSpecies', // relationshipId
|
|
302
|
+
* 'pets', // localTableId to link from
|
|
303
|
+
* 'species', // remoteTableId to link to
|
|
304
|
+
* 'species', // cellId containing remote key
|
|
305
|
+
* );
|
|
306
|
+
*
|
|
307
|
+
* console.log(relationships.getRemoteRowId('petSpecies', 'fido'));
|
|
308
|
+
* // -> 'dog'
|
|
309
|
+
* console.log(relationships.getLocalRowIds('petSpecies', 'dog'));
|
|
310
|
+
* // -> ['fido', 'cujo']
|
|
311
|
+
* ```
|
|
312
|
+
* @example
|
|
313
|
+
* This example creates a Store, creates a Relationships object, and defines
|
|
314
|
+
* a linked list Relationship based on the values in the `next` Cell of the
|
|
315
|
+
* `pets` Table that relates a Row to another in the same Table.
|
|
316
|
+
*
|
|
317
|
+
* ```js
|
|
318
|
+
* const store = createStore().setTable('pets', {
|
|
319
|
+
* fido: {species: 'dog', next: 'felix'},
|
|
320
|
+
* felix: {species: 'cat', next: 'cujo'},
|
|
321
|
+
* cujo: {species: 'dog'},
|
|
322
|
+
* });
|
|
323
|
+
*
|
|
324
|
+
* const relationships = createRelationships(store);
|
|
325
|
+
* relationships.setRelationshipDefinition(
|
|
326
|
+
* 'petSequence', // relationshipId
|
|
327
|
+
* 'pets', // localTableId to link from
|
|
328
|
+
* 'pets', // the same remoteTableId to link within
|
|
329
|
+
* 'next', // cellId containing link key
|
|
330
|
+
* );
|
|
331
|
+
*
|
|
332
|
+
* console.log(relationships.getLinkedRowIds('petSequence', 'fido'));
|
|
333
|
+
* // -> ['fido', 'felix', 'cujo']
|
|
334
|
+
* ```
|
|
335
|
+
* @category Configuration
|
|
336
|
+
*/
|
|
337
|
+
setRelationshipDefinition(
|
|
338
|
+
relationshipId: Id,
|
|
339
|
+
localTableId: Id,
|
|
340
|
+
remoteTableId: Id,
|
|
341
|
+
getRemoteRowId: Id | ((getCell: GetCell, localRowId: Id) => Id),
|
|
342
|
+
): Relationships;
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* The delRelationshipDefinition method removes an existing Relationship
|
|
346
|
+
* definition.
|
|
347
|
+
*
|
|
348
|
+
* @param relationshipId The Id of the Relationship to remove.
|
|
349
|
+
* @returns A reference to the Relationships object.
|
|
350
|
+
* @example
|
|
351
|
+
* This example creates a Store, creates a Relationships object, defines a
|
|
352
|
+
* simple Relationship, and then removes it.
|
|
353
|
+
*
|
|
354
|
+
* ```js
|
|
355
|
+
* const store = createStore()
|
|
356
|
+
* .setTable('pets', {
|
|
357
|
+
* fido: {species: 'dog'},
|
|
358
|
+
* felix: {species: 'cat'},
|
|
359
|
+
* cujo: {species: 'dog'},
|
|
360
|
+
* })
|
|
361
|
+
* .setTable('species', {
|
|
362
|
+
* dog: {price: 5},
|
|
363
|
+
* cat: {price: 4},
|
|
364
|
+
* });
|
|
365
|
+
*
|
|
366
|
+
* const relationships = createRelationships(store);
|
|
367
|
+
* relationships.setRelationshipDefinition(
|
|
368
|
+
* 'petSpecies',
|
|
369
|
+
* 'pets',
|
|
370
|
+
* 'species',
|
|
371
|
+
* 'species',
|
|
372
|
+
* );
|
|
373
|
+
* console.log(relationships.getRelationshipIds());
|
|
374
|
+
* // -> ['petSpecies']
|
|
375
|
+
*
|
|
376
|
+
* relationships.delRelationshipDefinition('petSpecies');
|
|
377
|
+
* console.log(relationships.getRelationshipIds());
|
|
378
|
+
* // -> []
|
|
379
|
+
* ```
|
|
380
|
+
* @category Configuration
|
|
381
|
+
*/
|
|
382
|
+
delRelationshipDefinition(relationshipId: Id): Relationships;
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* The getStore method returns a reference to the underlying Store that is
|
|
386
|
+
* backing this Relationships object.
|
|
387
|
+
*
|
|
388
|
+
* @returns A reference to the Store.
|
|
389
|
+
* @example
|
|
390
|
+
* This example creates a Relationships object against a newly-created Store
|
|
391
|
+
* and then gets its reference in order to update its data.
|
|
392
|
+
*
|
|
393
|
+
* ```js
|
|
394
|
+
* const relationships = createRelationships(createStore());
|
|
395
|
+
* relationships.setRelationshipDefinition(
|
|
396
|
+
* 'petSpecies',
|
|
397
|
+
* 'pets',
|
|
398
|
+
* 'species',
|
|
399
|
+
* 'species',
|
|
400
|
+
* );
|
|
401
|
+
* relationships.getStore().setCell('pets', 'fido', 'species', 'dog');
|
|
402
|
+
* console.log(relationships.getRemoteRowId('petSpecies', 'fido'));
|
|
403
|
+
* // -> 'dog'
|
|
404
|
+
* ```
|
|
405
|
+
* @category Getter
|
|
406
|
+
*/
|
|
407
|
+
getStore(): Store;
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* The getRelationshipIds method returns an array of the Relationship Ids
|
|
411
|
+
* registered with this Relationships object.
|
|
412
|
+
*
|
|
413
|
+
* @returns An array of Ids.
|
|
414
|
+
* @example
|
|
415
|
+
* This example creates a Relationships object with two definitions, and then
|
|
416
|
+
* gets the Ids of the definitions.
|
|
417
|
+
*
|
|
418
|
+
* ```js
|
|
419
|
+
* const relationships = createRelationships(createStore())
|
|
420
|
+
* .setRelationshipDefinition('petSpecies', 'pets', 'species', 'species')
|
|
421
|
+
* .setRelationshipDefinition('petSequence', 'pets', 'pets', 'next');
|
|
422
|
+
* console.log(relationships.getRelationshipIds());
|
|
423
|
+
* // -> ['petSpecies', 'petSequence']
|
|
424
|
+
* ```
|
|
425
|
+
* @category Getter
|
|
426
|
+
*/
|
|
427
|
+
getRelationshipIds(): Ids;
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* The forEachRelationship method takes a function that it will then call for
|
|
431
|
+
* each Relationship in a specified Relationships object.
|
|
432
|
+
*
|
|
433
|
+
* This method is useful for iterating over the structure of the Relationships
|
|
434
|
+
* object in a functional style. The `relationshipCallback` parameter is a
|
|
435
|
+
* RelationshipCallback function that will be called with the Id of each
|
|
436
|
+
* Relationship, and with a function that can then be used to iterate over
|
|
437
|
+
* each local Row involved in the Relationship.
|
|
438
|
+
*
|
|
439
|
+
* @param relationshipCallback The function that should be called for every
|
|
440
|
+
* Relationship.
|
|
441
|
+
* @example
|
|
442
|
+
* This example iterates over each Relationship in a Relationships object, and
|
|
443
|
+
* lists each Row Id within them.
|
|
444
|
+
*
|
|
445
|
+
* ```js
|
|
446
|
+
* const store = createStore().setTable('pets', {
|
|
447
|
+
* fido: {species: 'dog', next: 'felix'},
|
|
448
|
+
* felix: {species: 'cat', next: 'cujo'},
|
|
449
|
+
* cujo: {species: 'dog'},
|
|
450
|
+
* });
|
|
451
|
+
* const relationships = createRelationships(store)
|
|
452
|
+
* .setRelationshipDefinition('petSpecies', 'pets', 'species', 'species')
|
|
453
|
+
* .setRelationshipDefinition('petSequence', 'pets', 'pets', 'next');
|
|
454
|
+
*
|
|
455
|
+
* relationships.forEachRelationship((relationshipId, forEachRow) => {
|
|
456
|
+
* console.log(relationshipId);
|
|
457
|
+
* forEachRow((rowId) => console.log(`- ${rowId}`));
|
|
458
|
+
* });
|
|
459
|
+
* // -> 'petSpecies'
|
|
460
|
+
* // -> '- fido'
|
|
461
|
+
* // -> '- felix'
|
|
462
|
+
* // -> '- cujo'
|
|
463
|
+
* // -> 'petSequence'
|
|
464
|
+
* // -> '- fido'
|
|
465
|
+
* // -> '- felix'
|
|
466
|
+
* // -> '- cujo'
|
|
467
|
+
* ```
|
|
468
|
+
* @category Iterator
|
|
469
|
+
*/
|
|
470
|
+
forEachRelationship(relationshipCallback: RelationshipCallback): void;
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* The hasRelationship method returns a boolean indicating whether a given
|
|
474
|
+
* Relationship exists in the Relationships object.
|
|
475
|
+
*
|
|
476
|
+
* @param relationshipId The Id of a possible Relationship in the
|
|
477
|
+
* Relationships object.
|
|
478
|
+
* @returns Whether a Relationship with that Id exists.
|
|
479
|
+
* @example
|
|
480
|
+
* This example shows two simple Relationship existence checks.
|
|
481
|
+
*
|
|
482
|
+
* ```js
|
|
483
|
+
* const relationships = createRelationships(
|
|
484
|
+
* createStore(),
|
|
485
|
+
* ).setRelationshipDefinition('petSpecies', 'pets', 'species', 'species');
|
|
486
|
+
* console.log(relationships.hasRelationship('petSpecies'));
|
|
487
|
+
* // -> true
|
|
488
|
+
* console.log(relationships.hasRelationship('petColor'));
|
|
489
|
+
* // -> false
|
|
490
|
+
* ```
|
|
491
|
+
* @category Getter
|
|
492
|
+
*/
|
|
493
|
+
hasRelationship(indexId: Id): boolean;
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* The getLocalTableId method returns the Id of the underlying local Table
|
|
497
|
+
* that is used in the Relationship.
|
|
498
|
+
*
|
|
499
|
+
* If the Relationship Id is invalid, the method returns `undefined`.
|
|
500
|
+
*
|
|
501
|
+
* @param relationshipId The Id of a Relationship.
|
|
502
|
+
* @returns The Id of the local Table backing the Relationship, or
|
|
503
|
+
* `undefined`.
|
|
504
|
+
* @example
|
|
505
|
+
* This example creates a Relationship object, a single Relationship
|
|
506
|
+
* definition, and then queries it (and a non-existent definition) to get the
|
|
507
|
+
* underlying local Table Id.
|
|
508
|
+
*
|
|
509
|
+
* ```js
|
|
510
|
+
* const relationships = createRelationships(createStore());
|
|
511
|
+
* relationships.setRelationshipDefinition(
|
|
512
|
+
* 'petSpecies',
|
|
513
|
+
* 'pets',
|
|
514
|
+
* 'species',
|
|
515
|
+
* 'species',
|
|
516
|
+
* );
|
|
517
|
+
*
|
|
518
|
+
* console.log(relationships.getLocalTableId('petSpecies'));
|
|
519
|
+
* // -> 'pets'
|
|
520
|
+
* console.log(relationships.getLocalTableId('petColor'));
|
|
521
|
+
* // -> undefined
|
|
522
|
+
* ```
|
|
523
|
+
* @category Getter
|
|
524
|
+
*/
|
|
525
|
+
getLocalTableId(relationshipId: Id): Id;
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* The getRemoteTableId method returns the Id of the underlying remote Table
|
|
529
|
+
* that is used in the Relationship.
|
|
530
|
+
*
|
|
531
|
+
* If the Relationship Id is invalid, the method returns `undefined`.
|
|
532
|
+
*
|
|
533
|
+
* @param relationshipId The Id of a Relationship.
|
|
534
|
+
* @returns The Id of the remote Table backing the Relationship, or
|
|
535
|
+
* `undefined`.
|
|
536
|
+
* @example
|
|
537
|
+
* This example creates a Relationship object, a single Relationship
|
|
538
|
+
* definition, and then queries it (and a non-existent definition) to get the
|
|
539
|
+
* underlying remote Table Id.
|
|
540
|
+
*
|
|
541
|
+
* ```js
|
|
542
|
+
* const relationships = createRelationships(createStore());
|
|
543
|
+
* relationships.setRelationshipDefinition(
|
|
544
|
+
* 'petSpecies',
|
|
545
|
+
* 'pets',
|
|
546
|
+
* 'species',
|
|
547
|
+
* 'species',
|
|
548
|
+
* );
|
|
549
|
+
*
|
|
550
|
+
* console.log(relationships.getRemoteTableId('petSpecies'));
|
|
551
|
+
* // -> 'species'
|
|
552
|
+
* console.log(relationships.getRemoteTableId('petColor'));
|
|
553
|
+
* // -> undefined
|
|
554
|
+
* ```
|
|
555
|
+
* @category Getter
|
|
556
|
+
*/
|
|
557
|
+
getRemoteTableId(relationshipId: Id): Id;
|
|
558
|
+
|
|
559
|
+
/**
|
|
560
|
+
* The getRemoteRowId method gets the remote Row Id for a given local Row in a
|
|
561
|
+
* Relationship.
|
|
562
|
+
*
|
|
563
|
+
* If the identified Relationship or Row does not exist (or if the definition
|
|
564
|
+
* references a Table that does not exist) then `undefined` is returned.
|
|
565
|
+
*
|
|
566
|
+
* @param relationshipId The Id of the Relationship.
|
|
567
|
+
* @param localRowId The Id of the local Row in the Relationship.
|
|
568
|
+
* @returns The remote Row Id in the Relationship, or `undefined`.
|
|
569
|
+
* @example
|
|
570
|
+
* This example creates a Store, creates a Relationships object, and defines
|
|
571
|
+
* a simple Relationship. It then uses getRemoteRowId to see the remote Row Id
|
|
572
|
+
* in the Relationship (and also the remote Row Ids for a local Row that does
|
|
573
|
+
* not exist, and for a Relationship that has not been defined).
|
|
574
|
+
*
|
|
575
|
+
* ```js
|
|
576
|
+
* const store = createStore()
|
|
577
|
+
* .setTable('pets', {
|
|
578
|
+
* fido: {species: 'dog'},
|
|
579
|
+
* felix: {species: 'cat'},
|
|
580
|
+
* cujo: {species: 'dog'},
|
|
581
|
+
* })
|
|
582
|
+
* .setTable('species', {
|
|
583
|
+
* dog: {price: 5},
|
|
584
|
+
* cat: {price: 4},
|
|
585
|
+
* });
|
|
586
|
+
*
|
|
587
|
+
* const relationships = createRelationships(store);
|
|
588
|
+
* relationships.setRelationshipDefinition(
|
|
589
|
+
* 'petSpecies',
|
|
590
|
+
* 'pets',
|
|
591
|
+
* 'species',
|
|
592
|
+
* 'species',
|
|
593
|
+
* );
|
|
594
|
+
*
|
|
595
|
+
* console.log(relationships.getRemoteRowId('petSpecies', 'fido'));
|
|
596
|
+
* // -> 'dog'
|
|
597
|
+
* console.log(relationships.getRemoteRowId('petSpecies', 'toto'));
|
|
598
|
+
* // -> undefined
|
|
599
|
+
* console.log(relationships.getRemoteRowId('petColor', 'fido'));
|
|
600
|
+
* // -> undefined
|
|
601
|
+
* ```
|
|
602
|
+
* @category Getter
|
|
603
|
+
*/
|
|
604
|
+
getRemoteRowId(relationshipId: Id, localRowId: Id): Id | undefined;
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* The getLocalRowIds method gets the local Row Ids for a given remote Row in
|
|
608
|
+
* a Relationship.
|
|
609
|
+
*
|
|
610
|
+
* If the identified Relationship or Row does not exist (or if the definition
|
|
611
|
+
* references a Table that does not exist) then an empty array is returned.
|
|
612
|
+
*
|
|
613
|
+
* @param relationshipId The Id of the Relationship.
|
|
614
|
+
* @param remoteRowId The Id of the remote Row in the Relationship.
|
|
615
|
+
* @returns The local Row Ids in the Relationship, or an empty array.
|
|
616
|
+
* @example
|
|
617
|
+
* This example creates a Store, creates a Relationships object, and defines
|
|
618
|
+
* a simple Relationship. It then uses getLocalRowIds to see the local Row Ids
|
|
619
|
+
* in the Relationship (and also the local Row Ids for a remote Row that does
|
|
620
|
+
* not exist, and for a Relationship that has not been defined).
|
|
621
|
+
*
|
|
622
|
+
* ```js
|
|
623
|
+
* const store = createStore()
|
|
624
|
+
* .setTable('pets', {
|
|
625
|
+
* fido: {species: 'dog'},
|
|
626
|
+
* felix: {species: 'cat'},
|
|
627
|
+
* cujo: {species: 'dog'},
|
|
628
|
+
* })
|
|
629
|
+
* .setTable('species', {
|
|
630
|
+
* dog: {price: 5},
|
|
631
|
+
* cat: {price: 4},
|
|
632
|
+
* });
|
|
633
|
+
*
|
|
634
|
+
* const relationships = createRelationships(store);
|
|
635
|
+
* relationships.setRelationshipDefinition(
|
|
636
|
+
* 'petSpecies',
|
|
637
|
+
* 'pets',
|
|
638
|
+
* 'species',
|
|
639
|
+
* 'species',
|
|
640
|
+
* );
|
|
641
|
+
*
|
|
642
|
+
* console.log(relationships.getLocalRowIds('petSpecies', 'dog'));
|
|
643
|
+
* // -> ['fido', 'cujo']
|
|
644
|
+
* console.log(relationships.getLocalRowIds('petSpecies', 'worm'));
|
|
645
|
+
* // -> []
|
|
646
|
+
* console.log(relationships.getLocalRowIds('petColor', 'brown'));
|
|
647
|
+
* // -> []
|
|
648
|
+
* ```
|
|
649
|
+
* @category Getter
|
|
650
|
+
*/
|
|
651
|
+
getLocalRowIds(relationshipId: Id, remoteRowId: Id): Ids;
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
* The getLinkedRowIds method gets the linked Row Ids for a given Row in a
|
|
655
|
+
* linked list Relationship.
|
|
656
|
+
*
|
|
657
|
+
* A linked list Relationship is one that has the same Table specified as both
|
|
658
|
+
* local Table Id and remote Table Id, allowing you to create a sequence of
|
|
659
|
+
* Row objects within that one Table.
|
|
660
|
+
*
|
|
661
|
+
* If the identified Relationship or Row does not exist (or if the definition
|
|
662
|
+
* references a Table that does not exist) then an array containing just the
|
|
663
|
+
* first Row Id is returned.
|
|
664
|
+
*
|
|
665
|
+
* @param relationshipId The Id of the Relationship.
|
|
666
|
+
* @param firstRowId The Id of the first Row in the linked list Relationship.
|
|
667
|
+
* @returns The linked Row Ids in the Relationship.
|
|
668
|
+
* @example
|
|
669
|
+
* This example creates a Store, creates a Relationships object, and defines
|
|
670
|
+
* a simple linked list Relationship. It then uses getLinkedRowIds to see the
|
|
671
|
+
* linked Row Ids in the Relationship (and also the linked Row Ids for a Row
|
|
672
|
+
* that does not exist, and for a Relationship that has not been defined).
|
|
673
|
+
*
|
|
674
|
+
* ```js
|
|
675
|
+
* const store = createStore().setTable('pets', {
|
|
676
|
+
* fido: {species: 'dog', next: 'felix'},
|
|
677
|
+
* felix: {species: 'cat', next: 'cujo'},
|
|
678
|
+
* cujo: {species: 'dog'},
|
|
679
|
+
* });
|
|
680
|
+
*
|
|
681
|
+
* const relationships = createRelationships(store);
|
|
682
|
+
* relationships.setRelationshipDefinition(
|
|
683
|
+
* 'petSequence',
|
|
684
|
+
* 'pets',
|
|
685
|
+
* 'pets',
|
|
686
|
+
* 'next',
|
|
687
|
+
* );
|
|
688
|
+
*
|
|
689
|
+
* console.log(relationships.getLinkedRowIds('petSequence', 'fido'));
|
|
690
|
+
* // -> ['fido', 'felix', 'cujo']
|
|
691
|
+
* console.log(relationships.getLinkedRowIds('petSequence', 'felix'));
|
|
692
|
+
* // -> ['felix', 'cujo']
|
|
693
|
+
* console.log(relationships.getLinkedRowIds('petSequence', 'toto'));
|
|
694
|
+
* // -> ['toto']
|
|
695
|
+
* console.log(relationships.getLinkedRowIds('petFriendships', 'fido'));
|
|
696
|
+
* // -> ['fido']
|
|
697
|
+
* ```
|
|
698
|
+
* @category Getter
|
|
699
|
+
*/
|
|
700
|
+
getLinkedRowIds(relationshipId: Id, firstRowId: Id): Ids;
|
|
701
|
+
|
|
702
|
+
/**
|
|
703
|
+
* The addRemoteRowIdListener method registers a listener function with the
|
|
704
|
+
* Relationships object that will be called whenever a remote Row Id in a
|
|
705
|
+
* Relationship changes.
|
|
706
|
+
*
|
|
707
|
+
* You can either listen to a single local Row (by specifying the Relationship
|
|
708
|
+
* Id and local Row Id as the method's first two parameters), or changes to
|
|
709
|
+
* any local Row (by providing a `null` wildcards).
|
|
710
|
+
*
|
|
711
|
+
* Both, either, or neither of the `relationshipId` and `localRowId`
|
|
712
|
+
* parameters can be wildcarded with `null`. You can listen to a specific
|
|
713
|
+
* local Row in a specific Relationship, any local Row in a specific
|
|
714
|
+
* Relationship, a specific local Row in any Relationship, or any local Row in
|
|
715
|
+
* any Relationship.
|
|
716
|
+
*
|
|
717
|
+
* The provided listener is a RemoteRowIdListener function, and will be called
|
|
718
|
+
* with a reference to the Relationships object, the Id of the Relationship,
|
|
719
|
+
* and the Id of the local Row that had its remote Row change.
|
|
720
|
+
*
|
|
721
|
+
* @param relationshipId The Id of the Relationship to listen to, or `null` as
|
|
722
|
+
* a wildcard.
|
|
723
|
+
* @param localRowId The Id of the local Row to listen to, or `null` as a
|
|
724
|
+
* wildcard.
|
|
725
|
+
* @param listener The function that will be called whenever the remote Row Id
|
|
726
|
+
* changes.
|
|
727
|
+
* @returns A unique Id for the listener that can later be used to remove it.
|
|
728
|
+
* @example
|
|
729
|
+
* This example creates a Store, a Relationships object, and then registers a
|
|
730
|
+
* listener that responds to any changes to a specific local Row's remote Row.
|
|
731
|
+
*
|
|
732
|
+
* ```js
|
|
733
|
+
* const store = createStore()
|
|
734
|
+
* .setTable('pets', {
|
|
735
|
+
* fido: {species: 'dog'},
|
|
736
|
+
* felix: {species: 'cat'},
|
|
737
|
+
* cujo: {species: 'dog'},
|
|
738
|
+
* })
|
|
739
|
+
* .setTable('species', {
|
|
740
|
+
* wolf: {price: 10},
|
|
741
|
+
* dog: {price: 5},
|
|
742
|
+
* cat: {price: 4},
|
|
743
|
+
* });
|
|
744
|
+
*
|
|
745
|
+
* const relationships = createRelationships(store);
|
|
746
|
+
* relationships.setRelationshipDefinition(
|
|
747
|
+
* 'petSpecies',
|
|
748
|
+
* 'pets',
|
|
749
|
+
* 'species',
|
|
750
|
+
* 'species',
|
|
751
|
+
* );
|
|
752
|
+
*
|
|
753
|
+
* const listenerId = relationships.addRemoteRowIdListener(
|
|
754
|
+
* 'petSpecies',
|
|
755
|
+
* 'cujo',
|
|
756
|
+
* (relationships, relationshipId, localRowId) => {
|
|
757
|
+
* console.log('petSpecies relationship (from cujo) changed');
|
|
758
|
+
* console.log(relationships.getRemoteRowId('petSpecies', 'cujo'));
|
|
759
|
+
* },
|
|
760
|
+
* );
|
|
761
|
+
*
|
|
762
|
+
* store.setCell('pets', 'cujo', 'species', 'wolf');
|
|
763
|
+
* // -> 'petSpecies relationship (from cujo) changed'
|
|
764
|
+
* // -> 'wolf'
|
|
765
|
+
*
|
|
766
|
+
* relationships.delListener(listenerId);
|
|
767
|
+
* ```
|
|
768
|
+
* @example
|
|
769
|
+
* This example creates a Store, a Relationships object, and then registers a
|
|
770
|
+
* listener that responds to any changes to any local Row's remote Row. It
|
|
771
|
+
* also illustrates how you can use the getStore method and the getRemoteRowId
|
|
772
|
+
* method to resolve the remote Row as a whole.
|
|
773
|
+
*
|
|
774
|
+
* ```js
|
|
775
|
+
* const store = createStore()
|
|
776
|
+
* .setTable('pets', {
|
|
777
|
+
* fido: {species: 'dog', color: 'brown'},
|
|
778
|
+
* felix: {species: 'cat', color: 'black'},
|
|
779
|
+
* cujo: {species: 'dog', color: 'brown'},
|
|
780
|
+
* })
|
|
781
|
+
* .setTable('species', {
|
|
782
|
+
* wolf: {price: 10},
|
|
783
|
+
* dog: {price: 5},
|
|
784
|
+
* cat: {price: 4},
|
|
785
|
+
* })
|
|
786
|
+
* .setTable('color', {
|
|
787
|
+
* brown: {discount: 0.1},
|
|
788
|
+
* black: {discount: 0},
|
|
789
|
+
* grey: {discount: 0.2},
|
|
790
|
+
* });
|
|
791
|
+
*
|
|
792
|
+
* const relationships = createRelationships(store)
|
|
793
|
+
* .setRelationshipDefinition('petSpecies', 'pets', 'species', 'species')
|
|
794
|
+
* .setRelationshipDefinition('petColor', 'pets', 'color', 'color');
|
|
795
|
+
*
|
|
796
|
+
* const listenerId = relationships.addRemoteRowIdListener(
|
|
797
|
+
* null,
|
|
798
|
+
* null,
|
|
799
|
+
* (relationships, relationshipId, localRowId) => {
|
|
800
|
+
* console.log(
|
|
801
|
+
* `${relationshipId} relationship (from ${localRowId}) changed`,
|
|
802
|
+
* );
|
|
803
|
+
* console.log(relationships.getRemoteRowId(relationshipId, localRowId));
|
|
804
|
+
* console.log(
|
|
805
|
+
* relationships
|
|
806
|
+
* .getStore()
|
|
807
|
+
* .getRow(
|
|
808
|
+
* relationships.getRemoteTableId(relationshipId),
|
|
809
|
+
* relationships.getRemoteRowId(relationshipId, localRowId),
|
|
810
|
+
* ),
|
|
811
|
+
* );
|
|
812
|
+
* },
|
|
813
|
+
* );
|
|
814
|
+
*
|
|
815
|
+
* store.setRow('pets', 'cujo', {species: 'wolf', color: 'grey'});
|
|
816
|
+
* // -> 'petSpecies relationship (from cujo) changed'
|
|
817
|
+
* // -> 'wolf'
|
|
818
|
+
* // -> {price: 10}
|
|
819
|
+
* // -> 'petColor relationship (from cujo) changed'
|
|
820
|
+
* // -> 'grey'
|
|
821
|
+
* // -> {discount: 0.2}
|
|
822
|
+
*
|
|
823
|
+
* relationships.delListener(listenerId);
|
|
824
|
+
* ```
|
|
825
|
+
* @category Listener
|
|
826
|
+
*/
|
|
827
|
+
addRemoteRowIdListener(
|
|
828
|
+
relationshipId: IdOrNull,
|
|
829
|
+
localRowId: IdOrNull,
|
|
830
|
+
listener: RemoteRowIdListener,
|
|
831
|
+
): Id;
|
|
832
|
+
|
|
833
|
+
/**
|
|
834
|
+
* The addLocalRowIdsListener method registers a listener function with the
|
|
835
|
+
* Relationships object that will be called whenever the local Row Ids in
|
|
836
|
+
* a Relationship change.
|
|
837
|
+
*
|
|
838
|
+
* You can either listen to a single local Row (by specifying the Relationship
|
|
839
|
+
* Id and local Row Id as the method's first two parameters), or changes to
|
|
840
|
+
* any local Row (by providing a `null` wildcards).
|
|
841
|
+
*
|
|
842
|
+
* Both, either, or neither of the `relationshipId` and `remoteRowId`
|
|
843
|
+
* parameters can be wildcarded with `null`. You can listen to a specific
|
|
844
|
+
* remote Row in a specific Relationship, any remote Row in a specific
|
|
845
|
+
* Relationship, a specific remote Row in any Relationship, or any remote Row
|
|
846
|
+
* in any Relationship.
|
|
847
|
+
*
|
|
848
|
+
* The provided listener is a LocalRowIdsListener function, and will be called
|
|
849
|
+
* with a reference to the Relationships object, the Id of the Relationship,
|
|
850
|
+
* and the Id of the remote Row that had its local Row objects change.
|
|
851
|
+
*
|
|
852
|
+
* @param relationshipId The Id of the Relationship to listen to, or `null` as
|
|
853
|
+
* a wildcard.
|
|
854
|
+
* @param remoteRowId The Id of the remote Row to listen to, or `null` as a
|
|
855
|
+
* wildcard.
|
|
856
|
+
* @param listener The function that will be called whenever the local Row Ids
|
|
857
|
+
* change.
|
|
858
|
+
* @returns A unique Id for the listener that can later be used to remove it.
|
|
859
|
+
* @example
|
|
860
|
+
* This example creates a Store, a Relationships object, and then registers a
|
|
861
|
+
* listener that responds to any changes to a specific remote Row's local Row
|
|
862
|
+
* objects.
|
|
863
|
+
*
|
|
864
|
+
* ```js
|
|
865
|
+
* const store = createStore()
|
|
866
|
+
* .setTable('pets', {
|
|
867
|
+
* fido: {species: 'dog'},
|
|
868
|
+
* felix: {species: 'cat'},
|
|
869
|
+
* cujo: {species: 'dog'},
|
|
870
|
+
* })
|
|
871
|
+
* .setTable('species', {
|
|
872
|
+
* wolf: {price: 10},
|
|
873
|
+
* dog: {price: 5},
|
|
874
|
+
* cat: {price: 4},
|
|
875
|
+
* });
|
|
876
|
+
*
|
|
877
|
+
* const relationships = createRelationships(store);
|
|
878
|
+
* relationships.setRelationshipDefinition(
|
|
879
|
+
* 'petSpecies',
|
|
880
|
+
* 'pets',
|
|
881
|
+
* 'species',
|
|
882
|
+
* 'species',
|
|
883
|
+
* );
|
|
884
|
+
*
|
|
885
|
+
* const listenerId = relationships.addLocalRowIdsListener(
|
|
886
|
+
* 'petSpecies',
|
|
887
|
+
* 'dog',
|
|
888
|
+
* (relationships, relationshipId, remoteRowId) => {
|
|
889
|
+
* console.log('petSpecies relationship (to dog) changed');
|
|
890
|
+
* console.log(relationships.getLocalRowIds('petSpecies', 'dog'));
|
|
891
|
+
* },
|
|
892
|
+
* );
|
|
893
|
+
*
|
|
894
|
+
* store.setRow('pets', 'toto', {species: 'dog'});
|
|
895
|
+
* // -> 'petSpecies relationship (to dog) changed'
|
|
896
|
+
* // -> ['fido', 'cujo', 'toto']
|
|
897
|
+
*
|
|
898
|
+
* relationships.delListener(listenerId);
|
|
899
|
+
* ```
|
|
900
|
+
* @example
|
|
901
|
+
* This example creates a Store, a Relationships object, and then registers a
|
|
902
|
+
* listener that responds to any changes to any remote Row's local Row
|
|
903
|
+
* objects.
|
|
904
|
+
*
|
|
905
|
+
* ```js
|
|
906
|
+
* const store = createStore()
|
|
907
|
+
* .setTable('pets', {
|
|
908
|
+
* fido: {species: 'dog', color: 'brown'},
|
|
909
|
+
* felix: {species: 'cat', color: 'black'},
|
|
910
|
+
* cujo: {species: 'dog', color: 'brown'},
|
|
911
|
+
* toto: {species: 'dog', color: 'grey'},
|
|
912
|
+
* })
|
|
913
|
+
* .setTable('species', {
|
|
914
|
+
* wolf: {price: 10},
|
|
915
|
+
* dog: {price: 5},
|
|
916
|
+
* cat: {price: 4},
|
|
917
|
+
* })
|
|
918
|
+
* .setTable('color', {
|
|
919
|
+
* brown: {discount: 0.1},
|
|
920
|
+
* black: {discount: 0},
|
|
921
|
+
* grey: {discount: 0.2},
|
|
922
|
+
* });
|
|
923
|
+
*
|
|
924
|
+
* const relationships = createRelationships(store)
|
|
925
|
+
* .setRelationshipDefinition('petSpecies', 'pets', 'species', 'species')
|
|
926
|
+
* .setRelationshipDefinition('petColor', 'pets', 'color', 'color');
|
|
927
|
+
*
|
|
928
|
+
* const listenerId = relationships.addLocalRowIdsListener(
|
|
929
|
+
* null,
|
|
930
|
+
* null,
|
|
931
|
+
* (relationships, relationshipId, remoteRowId) => {
|
|
932
|
+
* console.log(
|
|
933
|
+
* `${relationshipId} relationship (to ${remoteRowId}) changed`,
|
|
934
|
+
* );
|
|
935
|
+
* console.log(relationships.getLocalRowIds(relationshipId, remoteRowId));
|
|
936
|
+
* },
|
|
937
|
+
* );
|
|
938
|
+
*
|
|
939
|
+
* store.setRow('pets', 'cujo', {species: 'wolf', color: 'grey'});
|
|
940
|
+
* // -> 'petSpecies relationship (to dog) changed'
|
|
941
|
+
* // -> ['fido', 'toto']
|
|
942
|
+
* // -> 'petSpecies relationship (to wolf) changed'
|
|
943
|
+
* // -> ['cujo']
|
|
944
|
+
* // -> 'petColor relationship (to brown) changed'
|
|
945
|
+
* // -> ['fido']
|
|
946
|
+
* // -> 'petColor relationship (to grey) changed'
|
|
947
|
+
* // -> ['toto', 'cujo']
|
|
948
|
+
*
|
|
949
|
+
* relationships.delListener(listenerId);
|
|
950
|
+
* ```
|
|
951
|
+
* @category Listener
|
|
952
|
+
*/
|
|
953
|
+
addLocalRowIdsListener(
|
|
954
|
+
relationshipId: IdOrNull,
|
|
955
|
+
remoteRowId: IdOrNull,
|
|
956
|
+
listener: LocalRowIdsListener,
|
|
957
|
+
): Id;
|
|
958
|
+
|
|
959
|
+
/**
|
|
960
|
+
* The addLinkedRowIdsListener method registers a listener function with the
|
|
961
|
+
* Relationships object that will be called whenever the linked Row Ids in a
|
|
962
|
+
* linked list Relationship change.
|
|
963
|
+
*
|
|
964
|
+
* A linked list Relationship is one that has the same Table specified as both
|
|
965
|
+
* local Table Id and remote Table Id, allowing you to create a sequence of
|
|
966
|
+
* Row objects within that one Table.
|
|
967
|
+
*
|
|
968
|
+
* You listen to changes to a linked list starting from a single first Row by
|
|
969
|
+
* specifying the Relationship Id and local Row Id as the method's first two
|
|
970
|
+
* parameters.
|
|
971
|
+
*
|
|
972
|
+
* Unlike other listener registration methods, you cannot provide `null`
|
|
973
|
+
* wildcards for the first two parameters of the addLinkedRowIdsListener
|
|
974
|
+
* method. This prevents the prohibitive expense of tracking all the possible
|
|
975
|
+
* linked lists (and partial linked lists within them) in a Store.
|
|
976
|
+
*
|
|
977
|
+
* The provided listener is a LinkedRowIdsListener function, and will be
|
|
978
|
+
* called with a reference to the Relationships object, the Id of the
|
|
979
|
+
* Relationship, and the Id of the first Row that had its linked list change.
|
|
980
|
+
*
|
|
981
|
+
* @param relationshipId The Id of the Relationship to listen to.
|
|
982
|
+
* @param firstRowId The Id of the first Row of the linked list to listen to.
|
|
983
|
+
* @param listener The function that will be called whenever the linked Row
|
|
984
|
+
* Ids change.
|
|
985
|
+
* @returns A unique Id for the listener that can later be used to remove it.
|
|
986
|
+
* @example
|
|
987
|
+
* This example creates a Store, a Relationships object, and then registers a
|
|
988
|
+
* listener that responds to any changes to a specific first Row's linked Row
|
|
989
|
+
* objects.
|
|
990
|
+
*
|
|
991
|
+
* ```js
|
|
992
|
+
* const store = createStore().setTable('pets', {
|
|
993
|
+
* fido: {species: 'dog', next: 'felix'},
|
|
994
|
+
* felix: {species: 'cat', next: 'cujo'},
|
|
995
|
+
* cujo: {species: 'dog'},
|
|
996
|
+
* });
|
|
997
|
+
*
|
|
998
|
+
* const relationships = createRelationships(store);
|
|
999
|
+
* relationships.setRelationshipDefinition(
|
|
1000
|
+
* 'petSequence',
|
|
1001
|
+
* 'pets',
|
|
1002
|
+
* 'pets',
|
|
1003
|
+
* 'next',
|
|
1004
|
+
* );
|
|
1005
|
+
*
|
|
1006
|
+
* const listenerId = relationships.addLinkedRowIdsListener(
|
|
1007
|
+
* 'petSequence',
|
|
1008
|
+
* 'fido',
|
|
1009
|
+
* (relationships, relationshipId, firstRowId) => {
|
|
1010
|
+
* console.log('petSequence linked list (from fido) changed');
|
|
1011
|
+
* console.log(relationships.getLinkedRowIds('petSequence', 'fido'));
|
|
1012
|
+
* },
|
|
1013
|
+
* );
|
|
1014
|
+
*
|
|
1015
|
+
* store.setRow('pets', 'toto', {species: 'dog'});
|
|
1016
|
+
* store.setCell('pets', 'cujo', 'next', 'toto');
|
|
1017
|
+
* // -> 'petSequence linked list (from fido) changed'
|
|
1018
|
+
* // -> ['fido', 'felix', 'cujo', 'toto']
|
|
1019
|
+
*
|
|
1020
|
+
* relationships.delListener(listenerId);
|
|
1021
|
+
* ```
|
|
1022
|
+
* @category Listener
|
|
1023
|
+
*/
|
|
1024
|
+
addLinkedRowIdsListener(
|
|
1025
|
+
relationshipId: Id,
|
|
1026
|
+
firstRowId: Id,
|
|
1027
|
+
listener: LinkedRowIdsListener,
|
|
1028
|
+
): Id;
|
|
1029
|
+
|
|
1030
|
+
/**
|
|
1031
|
+
* The delListener method removes a listener that was previously added to the
|
|
1032
|
+
* Relationships object.
|
|
1033
|
+
*
|
|
1034
|
+
* Use the Id returned by whichever method was used to add the listener. Note
|
|
1035
|
+
* that the Relationships object may re-use this Id for future listeners added
|
|
1036
|
+
* to it.
|
|
1037
|
+
*
|
|
1038
|
+
* @param listenerId The Id of the listener to remove.
|
|
1039
|
+
* @returns A reference to the Relationships object.
|
|
1040
|
+
* @example
|
|
1041
|
+
* This example creates a Store, a Relationships object, registers a listener,
|
|
1042
|
+
* and then removes it.
|
|
1043
|
+
*
|
|
1044
|
+
* ```js
|
|
1045
|
+
* const store = createStore()
|
|
1046
|
+
* .setTable('pets', {
|
|
1047
|
+
* fido: {species: 'dog'},
|
|
1048
|
+
* felix: {species: 'cat'},
|
|
1049
|
+
* cujo: {species: 'dog'},
|
|
1050
|
+
* })
|
|
1051
|
+
* .setTable('species', {
|
|
1052
|
+
* wolf: {price: 10},
|
|
1053
|
+
* dog: {price: 5},
|
|
1054
|
+
* cat: {price: 4},
|
|
1055
|
+
* });
|
|
1056
|
+
*
|
|
1057
|
+
* const relationships = createRelationships(store);
|
|
1058
|
+
* relationships.setRelationshipDefinition(
|
|
1059
|
+
* 'petSpecies',
|
|
1060
|
+
* 'pets',
|
|
1061
|
+
* 'species',
|
|
1062
|
+
* 'species',
|
|
1063
|
+
* );
|
|
1064
|
+
*
|
|
1065
|
+
* const listenerId = relationships.addLocalRowIdsListener(
|
|
1066
|
+
* 'petSpecies',
|
|
1067
|
+
* 'dog',
|
|
1068
|
+
* (relationships, relationshipId, remoteRowId) => {
|
|
1069
|
+
* console.log('petSpecies relationship (to dog) changed');
|
|
1070
|
+
* },
|
|
1071
|
+
* );
|
|
1072
|
+
*
|
|
1073
|
+
* store.setRow('pets', 'toto', {species: 'dog'});
|
|
1074
|
+
* // -> 'petSpecies relationship (to dog) changed'
|
|
1075
|
+
*
|
|
1076
|
+
* relationships.delListener(listenerId);
|
|
1077
|
+
*
|
|
1078
|
+
* store.setRow('pets', 'toto', {species: 'dog'});
|
|
1079
|
+
* // -> undefined
|
|
1080
|
+
* // The listener is not called.
|
|
1081
|
+
* ```
|
|
1082
|
+
* @category Listener
|
|
1083
|
+
*/
|
|
1084
|
+
delListener(listenerId: Id): Relationships;
|
|
1085
|
+
|
|
1086
|
+
/**
|
|
1087
|
+
* The destroy method should be called when this Relationships object is no
|
|
1088
|
+
* longer used.
|
|
1089
|
+
*
|
|
1090
|
+
* This guarantees that all of the listeners that the object registered with
|
|
1091
|
+
* the underlying Store are removed and it can be correctly garbage collected.
|
|
1092
|
+
*
|
|
1093
|
+
* @example
|
|
1094
|
+
* This example creates a Store, adds a Relationships object with a
|
|
1095
|
+
* definition (that registers a RowListener with the underlying Store),
|
|
1096
|
+
* and then destroys it again, removing the listener.
|
|
1097
|
+
*
|
|
1098
|
+
* ```js
|
|
1099
|
+
* const store = createStore()
|
|
1100
|
+
* .setTable('pets', {
|
|
1101
|
+
* fido: {species: 'dog'},
|
|
1102
|
+
* felix: {species: 'cat'},
|
|
1103
|
+
* cujo: {species: 'dog'},
|
|
1104
|
+
* })
|
|
1105
|
+
* .setTable('species', {
|
|
1106
|
+
* wolf: {price: 10},
|
|
1107
|
+
* dog: {price: 5},
|
|
1108
|
+
* cat: {price: 4},
|
|
1109
|
+
* });
|
|
1110
|
+
*
|
|
1111
|
+
* const relationships = createRelationships(store);
|
|
1112
|
+
* relationships.setRelationshipDefinition(
|
|
1113
|
+
* 'petSpecies',
|
|
1114
|
+
* 'pets',
|
|
1115
|
+
* 'species',
|
|
1116
|
+
* 'species',
|
|
1117
|
+
* );
|
|
1118
|
+
* console.log(store.getListenerStats().row);
|
|
1119
|
+
* // -> 1
|
|
1120
|
+
*
|
|
1121
|
+
* relationships.destroy();
|
|
1122
|
+
*
|
|
1123
|
+
* console.log(store.getListenerStats().row);
|
|
1124
|
+
* // -> 0
|
|
1125
|
+
* ```
|
|
1126
|
+
* @category Lifecycle
|
|
1127
|
+
*/
|
|
1128
|
+
destroy(): void;
|
|
1129
|
+
|
|
1130
|
+
/**
|
|
1131
|
+
* The getListenerStats method provides a set of statistics about the
|
|
1132
|
+
* listeners registered with the Relationships object, and is used for
|
|
1133
|
+
* debugging purposes.
|
|
1134
|
+
*
|
|
1135
|
+
* The RelationshipsListenerStats object contains a breakdown of the different
|
|
1136
|
+
* types of listener.
|
|
1137
|
+
*
|
|
1138
|
+
* The statistics are only populated in a debug build: production builds
|
|
1139
|
+
* return an empty object. The method is intended to be used during
|
|
1140
|
+
* development to ensure your application is not leaking listener
|
|
1141
|
+
* registrations, for example.
|
|
1142
|
+
*
|
|
1143
|
+
* @returns A RelationshipsListenerStats object containing Relationships
|
|
1144
|
+
* listener statistics.
|
|
1145
|
+
* @example
|
|
1146
|
+
* This example gets the listener statistics of a Relationships object.
|
|
1147
|
+
*
|
|
1148
|
+
* ```js
|
|
1149
|
+
* const store = createStore();
|
|
1150
|
+
* const relationships = createRelationships(store);
|
|
1151
|
+
* relationships.addRemoteRowIdListener(null, null, () => {
|
|
1152
|
+
* console.log('Remote Row Id changed');
|
|
1153
|
+
* });
|
|
1154
|
+
* relationships.addLocalRowIdsListener(null, null, () => {
|
|
1155
|
+
* console.log('Local Row Id changed');
|
|
1156
|
+
* });
|
|
1157
|
+
*
|
|
1158
|
+
* const listenerStats = relationships.getListenerStats();
|
|
1159
|
+
* console.log(listenerStats.remoteRowId);
|
|
1160
|
+
* // -> 1
|
|
1161
|
+
* console.log(listenerStats.localRowIds);
|
|
1162
|
+
* // -> 1
|
|
1163
|
+
* ```
|
|
1164
|
+
* @category Development
|
|
1165
|
+
*/
|
|
1166
|
+
getListenerStats(): RelationshipsListenerStats;
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
/**
|
|
1170
|
+
* The createRelationships function creates a Relationships object, and is the
|
|
1171
|
+
* main entry point into the relationships module.
|
|
1172
|
+
*
|
|
1173
|
+
* A given Store can only have one Relationships object associated with it. If
|
|
1174
|
+
* you call this function twice on the same Store, your second call will return
|
|
1175
|
+
* a reference to the Relationships object created by the first.
|
|
1176
|
+
*
|
|
1177
|
+
* @param store The Store for which to register Relationships.
|
|
1178
|
+
* @returns A reference to the new Relationships object.
|
|
1179
|
+
* @example
|
|
1180
|
+
* This example creates a Relationships object.
|
|
1181
|
+
*
|
|
1182
|
+
* ```js
|
|
1183
|
+
* const store = createStore();
|
|
1184
|
+
* const relationships = createRelationships(store);
|
|
1185
|
+
* console.log(relationships.getRelationshipIds());
|
|
1186
|
+
* // -> []
|
|
1187
|
+
* ```
|
|
1188
|
+
* @example
|
|
1189
|
+
* This example creates a Relationships object, and calls the method a second
|
|
1190
|
+
* time for the same Store to return the same object.
|
|
1191
|
+
*
|
|
1192
|
+
* ```js
|
|
1193
|
+
* const store = createStore();
|
|
1194
|
+
* const relationships1 = createRelationships(store);
|
|
1195
|
+
* const relationships2 = createRelationships(store);
|
|
1196
|
+
* console.log(relationships1 === relationships2);
|
|
1197
|
+
* // -> true
|
|
1198
|
+
* ```
|
|
1199
|
+
* @category Creation
|
|
1200
|
+
*/
|
|
1201
|
+
export function createRelationships(store: Store): Relationships;
|