atom.io 0.14.7 → 0.15.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 +5 -0
- package/data/dist/index.cjs +200 -218
- package/data/dist/index.cjs.map +1 -1
- package/data/dist/index.d.ts +16 -7
- package/data/dist/index.js +202 -221
- package/data/dist/index.js.map +1 -1
- package/data/src/join.ts +295 -292
- package/data/src/struct-family.ts +2 -2
- package/data/src/struct.ts +2 -2
- package/dist/chunk-S7R5MU6A.js +137 -0
- package/dist/chunk-S7R5MU6A.js.map +1 -0
- package/dist/index.cjs +3 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +15 -8
- package/dist/index.js +1 -151
- package/dist/index.js.map +1 -1
- package/internal/dist/index.cjs +275 -200
- package/internal/dist/index.cjs.map +1 -1
- package/internal/dist/index.d.ts +43 -36
- package/internal/dist/index.js +221 -193
- package/internal/dist/index.js.map +1 -1
- package/internal/src/atom/create-atom.ts +5 -86
- package/internal/src/atom/create-regular-atom.ts +92 -0
- package/internal/src/atom/index.ts +16 -0
- package/internal/src/atom/is-default.ts +0 -5
- package/internal/src/caching.ts +14 -16
- package/internal/src/families/create-atom-family.ts +20 -46
- package/internal/src/families/create-readonly-selector-family.ts +1 -0
- package/internal/src/families/create-regular-atom-family.ts +72 -0
- package/internal/src/families/create-selector-family.ts +2 -0
- package/internal/src/families/index.ts +1 -0
- package/internal/src/mutable/create-mutable-atom-family.ts +2 -2
- package/internal/src/mutable/create-mutable-atom.ts +8 -3
- package/internal/src/mutable/get-update-family.ts +1 -1
- package/internal/src/mutable/is-mutable.ts +3 -30
- package/internal/src/mutable/tracker-family.ts +2 -2
- package/internal/src/mutable/tracker.ts +5 -5
- package/internal/src/operation.ts +14 -18
- package/internal/src/selector/create-read-write-selector.ts +2 -3
- package/internal/src/selector/create-selector.ts +1 -1
- package/internal/src/selector/register-selector.ts +9 -14
- package/internal/src/set-state/evict-downstream.ts +3 -5
- package/internal/src/set-state/set-atom.ts +14 -17
- package/internal/src/store/store.ts +23 -19
- package/internal/src/store/withdraw.ts +32 -70
- package/internal/src/subscribe/subscribe-to-root-atoms.ts +5 -3
- package/internal/src/subscribe/subscribe-to-state.ts +5 -3
- package/internal/src/transaction/apply-transaction.ts +20 -2
- package/internal/src/transaction/build-transaction.ts +19 -11
- package/internal/src/transaction/create-transaction.ts +6 -11
- package/internal/src/transaction/index.ts +2 -3
- package/introspection/dist/index.cjs +6 -6
- package/introspection/dist/index.cjs.map +1 -1
- package/introspection/dist/index.d.ts +3 -3
- package/introspection/dist/index.js +7 -7
- package/introspection/dist/index.js.map +1 -1
- package/introspection/src/attach-atom-index.ts +7 -2
- package/introspection/src/attach-selector-index.ts +7 -2
- package/introspection/src/attach-timeline-family.ts +5 -2
- package/introspection/src/attach-timeline-index.ts +2 -2
- package/introspection/src/attach-transaction-index.ts +2 -2
- package/introspection/src/attach-transaction-logs.ts +2 -2
- package/package.json +10 -8
- package/react/dist/index.cjs +9 -12
- package/react/dist/index.cjs.map +1 -1
- package/react/dist/index.js +9 -12
- package/react/dist/index.js.map +1 -1
- package/react/src/store-hooks.ts +10 -12
- package/react-devtools/dist/index.d.ts +17 -11
- package/src/atom.ts +8 -17
- package/src/selector.ts +3 -1
- package/src/set-state.ts +1 -3
- package/src/silo.ts +2 -14
- package/src/transaction.ts +17 -6
- package/transceivers/set-rtx/dist/index.cjs +2 -1
- package/transceivers/set-rtx/dist/index.cjs.map +1 -1
- package/transceivers/set-rtx/dist/index.js +2 -1
- package/transceivers/set-rtx/dist/index.js.map +1 -1
- package/transceivers/set-rtx/src/set-rtx.ts +2 -1
- package/internal/src/transaction/redo-transaction.ts +0 -27
- package/internal/src/transaction/undo-transaction.ts +0 -27
package/data/src/join.ts
CHANGED
|
@@ -6,12 +6,12 @@ import type {
|
|
|
6
6
|
Transactors,
|
|
7
7
|
Write,
|
|
8
8
|
} from "atom.io"
|
|
9
|
-
import { getState, setState } from "atom.io"
|
|
9
|
+
import { dispose, getState, setState } from "atom.io"
|
|
10
10
|
import type { Store } from "atom.io/internal"
|
|
11
11
|
import {
|
|
12
12
|
IMPLICIT,
|
|
13
|
-
createAtomFamily,
|
|
14
13
|
createMutableAtomFamily,
|
|
14
|
+
createRegularAtomFamily,
|
|
15
15
|
createSelectorFamily,
|
|
16
16
|
getJsonFamily,
|
|
17
17
|
} from "atom.io/internal"
|
|
@@ -21,7 +21,6 @@ import { SetRTX } from "atom.io/transceivers/set-rtx"
|
|
|
21
21
|
import type {
|
|
22
22
|
BaseExternalStoreConfiguration,
|
|
23
23
|
ExternalStoreConfiguration,
|
|
24
|
-
ExternalStoreWithContentConfiguration,
|
|
25
24
|
JunctionEntries,
|
|
26
25
|
JunctionSchema,
|
|
27
26
|
} from "~/packages/rel8/junction/src"
|
|
@@ -113,338 +112,342 @@ export type JoinState<
|
|
|
113
112
|
}
|
|
114
113
|
: never
|
|
115
114
|
|
|
116
|
-
export
|
|
115
|
+
export class Join<
|
|
117
116
|
const ASide extends string,
|
|
118
117
|
const BSide extends string,
|
|
119
|
-
const Cardinality extends Rel8.Cardinality,
|
|
120
|
-
>(
|
|
121
|
-
options: JoinOptions<ASide, BSide, Cardinality, null>,
|
|
122
|
-
defaultContent?: undefined,
|
|
123
|
-
store?: Store,
|
|
124
|
-
): {
|
|
125
|
-
relations: Junction<ASide, BSide>
|
|
126
|
-
findState: JoinState<ASide, BSide, Cardinality, null>
|
|
127
|
-
}
|
|
128
|
-
export function join<
|
|
129
|
-
const ASide extends string,
|
|
130
118
|
const Cardinality extends `1:1` | `1:n` | `n:n`,
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
a,
|
|
177
|
-
b,
|
|
178
|
-
) => {
|
|
179
|
-
const aKeys = getRelatedKeys(transactors, a)
|
|
180
|
-
const bKeys = getRelatedKeys(transactors, b)
|
|
181
|
-
if (aKeys) {
|
|
119
|
+
const Content extends Json.Object | null = null,
|
|
120
|
+
> {
|
|
121
|
+
private transactors: Transactors = TRANSACTORS
|
|
122
|
+
public relations: Junction<ASide, BSide, Content>
|
|
123
|
+
public findState: JoinState<ASide, BSide, Cardinality, Content>
|
|
124
|
+
public transact(
|
|
125
|
+
transactors: Transactors,
|
|
126
|
+
run: (join: Join<ASide, BSide, Cardinality, Content>) => void,
|
|
127
|
+
): void {
|
|
128
|
+
this.transactors = transactors
|
|
129
|
+
run(this)
|
|
130
|
+
this.transactors = TRANSACTORS
|
|
131
|
+
}
|
|
132
|
+
public constructor(
|
|
133
|
+
options: JoinOptions<ASide, BSide, Cardinality, Content>,
|
|
134
|
+
defaultContent: Content | undefined,
|
|
135
|
+
store: Store = IMPLICIT.STORE,
|
|
136
|
+
) {
|
|
137
|
+
const a: ASide = options.between[0]
|
|
138
|
+
const b: BSide = options.between[1]
|
|
139
|
+
const findRelatedKeysState = createMutableAtomFamily<
|
|
140
|
+
SetRTX<string>,
|
|
141
|
+
string[],
|
|
142
|
+
string
|
|
143
|
+
>(
|
|
144
|
+
{
|
|
145
|
+
key: `${options.key}/relatedKeys`,
|
|
146
|
+
default: () => new SetRTX(),
|
|
147
|
+
mutable: true,
|
|
148
|
+
fromJson: (json) => new SetRTX(json),
|
|
149
|
+
toJson: (set) => [...set],
|
|
150
|
+
},
|
|
151
|
+
store,
|
|
152
|
+
)
|
|
153
|
+
const getRelatedKeys: Read<(key: string) => SetRTX<string>> = (
|
|
154
|
+
{ get },
|
|
155
|
+
key,
|
|
156
|
+
) => get(findRelatedKeysState(key))
|
|
157
|
+
const addRelation: Write<(a: string, b: string) => void> = (
|
|
158
|
+
transactors,
|
|
159
|
+
a,
|
|
160
|
+
b,
|
|
161
|
+
) => {
|
|
162
|
+
const aKeys = getRelatedKeys(transactors, a)
|
|
163
|
+
const bKeys = getRelatedKeys(transactors, b)
|
|
182
164
|
transactors.set(findRelatedKeysState(a), aKeys.add(b))
|
|
183
|
-
} else {
|
|
184
|
-
transactors.set(findRelatedKeysState(a), new SetRTX([b]))
|
|
185
|
-
}
|
|
186
|
-
if (bKeys) {
|
|
187
165
|
transactors.set(findRelatedKeysState(b), bKeys.add(a))
|
|
188
|
-
} else {
|
|
189
|
-
transactors.set(findRelatedKeysState(b), new SetRTX([a]))
|
|
190
166
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
const aKeys = getRelatedKeys(transactors, a)
|
|
198
|
-
if (aKeys) {
|
|
167
|
+
const deleteRelation: Write<(a: string, b: string) => void> = (
|
|
168
|
+
transactors,
|
|
169
|
+
a,
|
|
170
|
+
b,
|
|
171
|
+
) => {
|
|
172
|
+
const aKeys = getRelatedKeys(transactors, a)
|
|
199
173
|
aKeys.delete(b)
|
|
200
174
|
if (aKeys.size === 0) {
|
|
201
|
-
|
|
175
|
+
dispose(findRelatedKeysState(a))
|
|
202
176
|
}
|
|
203
177
|
const bKeys = getRelatedKeys(transactors, b)
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
transactors.set(findRelatedKeysState(b), undefined)
|
|
208
|
-
}
|
|
178
|
+
bKeys.delete(a)
|
|
179
|
+
if (bKeys.size === 0) {
|
|
180
|
+
dispose(findRelatedKeysState(b))
|
|
209
181
|
}
|
|
210
182
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
const aRelations = getRelatedKeys(transactors, a)
|
|
218
|
-
if (aRelations) {
|
|
183
|
+
const replaceRelationsSafely: Write<(a: string, bs: string[]) => void> = (
|
|
184
|
+
transactors,
|
|
185
|
+
a,
|
|
186
|
+
bs,
|
|
187
|
+
) => {
|
|
188
|
+
const aRelations = getRelatedKeys(transactors, a)
|
|
219
189
|
for (const b of aRelations) {
|
|
220
190
|
const bKeys = getRelatedKeys(transactors, b)
|
|
221
191
|
if (bKeys) {
|
|
222
192
|
bKeys.delete(a)
|
|
223
193
|
if (bKeys.size === 0) {
|
|
224
|
-
|
|
194
|
+
dispose(findRelatedKeysState(b))
|
|
225
195
|
}
|
|
226
196
|
}
|
|
227
197
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
const bKeys = getRelatedKeys(transactors, b)
|
|
232
|
-
if (bKeys) {
|
|
198
|
+
transactors.set(findRelatedKeysState(a), new SetRTX(bs))
|
|
199
|
+
for (const b of bs) {
|
|
200
|
+
const bKeys = getRelatedKeys(transactors, b)
|
|
233
201
|
bKeys.add(a)
|
|
234
|
-
} else {
|
|
235
|
-
transactors.set(findRelatedKeysState(b), new SetRTX([a]))
|
|
236
202
|
}
|
|
237
203
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
let bKeys = getRelatedKeys(transactors, b)
|
|
247
|
-
if (bKeys) {
|
|
204
|
+
const replaceRelationsUnsafely: Write<(a: string, bs: string[]) => void> = (
|
|
205
|
+
transactors,
|
|
206
|
+
a,
|
|
207
|
+
bs,
|
|
208
|
+
) => {
|
|
209
|
+
transactors.set(findRelatedKeysState(a), new SetRTX(bs))
|
|
210
|
+
for (const b of bs) {
|
|
211
|
+
const bKeys = getRelatedKeys(transactors, b)
|
|
248
212
|
bKeys.add(a)
|
|
249
|
-
} else {
|
|
250
|
-
bKeys = new SetRTX([a])
|
|
251
|
-
transactors.set(findRelatedKeysState(b), bKeys)
|
|
252
213
|
}
|
|
253
214
|
}
|
|
254
|
-
|
|
255
|
-
const has: Read<(a: string, b?: string) => boolean> = (transactors, a, b) => {
|
|
256
|
-
const aKeys = getRelatedKeys(transactors, a)
|
|
257
|
-
return b ? aKeys?.has(b) ?? false : (aKeys?.size ?? 0) > 0 ?? false
|
|
258
|
-
}
|
|
259
|
-
const baseExternalStoreConfiguration: BaseExternalStoreConfiguration = {
|
|
260
|
-
getRelatedKeys: (key) => getRelatedKeys(TRANSACTORS, key),
|
|
261
|
-
addRelation: (a, b) => addRelation(TRANSACTORS, a, b),
|
|
262
|
-
deleteRelation: (a, b) => deleteRelation(TRANSACTORS, a, b),
|
|
263
|
-
replaceRelationsSafely: (a, bs) =>
|
|
264
|
-
replaceRelationsSafely(TRANSACTORS, a, bs),
|
|
265
|
-
replaceRelationsUnsafely: (a, bs) =>
|
|
266
|
-
replaceRelationsUnsafely(TRANSACTORS, a, bs),
|
|
267
|
-
has: (a, b) => has(TRANSACTORS, a, b),
|
|
268
|
-
}
|
|
269
|
-
let externalStore: ExternalStoreConfiguration<Content>
|
|
270
|
-
let findContentState: AtomFamily<Content, string>
|
|
271
|
-
if (defaultContent) {
|
|
272
|
-
findContentState = createAtomFamily<Content, string>(
|
|
273
|
-
{
|
|
274
|
-
key: `${options.key}/content`,
|
|
275
|
-
default: defaultContent,
|
|
276
|
-
},
|
|
277
|
-
store,
|
|
278
|
-
)
|
|
279
|
-
const getContent: Read<(key: string) => Content | undefined> = (
|
|
280
|
-
{ get },
|
|
281
|
-
key,
|
|
282
|
-
) => get(findContentState(key))
|
|
283
|
-
const setContent: Write<(key: string, content: Content) => void> = (
|
|
215
|
+
const has: Read<(a: string, b?: string) => boolean> = (
|
|
284
216
|
transactors,
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
) =>
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
217
|
+
a,
|
|
218
|
+
b,
|
|
219
|
+
) => {
|
|
220
|
+
const aKeys = getRelatedKeys(transactors, a)
|
|
221
|
+
return b ? aKeys.has(b) : aKeys.size > 0
|
|
222
|
+
}
|
|
223
|
+
const baseExternalStoreConfiguration: BaseExternalStoreConfiguration = {
|
|
224
|
+
getRelatedKeys: (key) => getRelatedKeys(this.transactors, key),
|
|
225
|
+
addRelation: (a, b) => addRelation(this.transactors, a, b),
|
|
226
|
+
deleteRelation: (a, b) => deleteRelation(this.transactors, a, b),
|
|
227
|
+
replaceRelationsSafely: (a, bs) =>
|
|
228
|
+
replaceRelationsSafely(this.transactors, a, bs),
|
|
229
|
+
replaceRelationsUnsafely: (a, bs) =>
|
|
230
|
+
replaceRelationsUnsafely(this.transactors, a, bs),
|
|
231
|
+
has: (a, b) => has(this.transactors, a, b),
|
|
232
|
+
}
|
|
233
|
+
let externalStore: ExternalStoreConfiguration<Content>
|
|
234
|
+
let findContentState: AtomFamily<Content, string>
|
|
235
|
+
if (defaultContent) {
|
|
236
|
+
findContentState = createRegularAtomFamily<Content, string>(
|
|
237
|
+
{
|
|
238
|
+
key: `${options.key}/content`,
|
|
239
|
+
default: defaultContent,
|
|
240
|
+
},
|
|
241
|
+
store,
|
|
242
|
+
)
|
|
243
|
+
const getContent: Read<(key: string) => Content | undefined> = (
|
|
244
|
+
{ get },
|
|
245
|
+
key,
|
|
246
|
+
) => get(findContentState(key))
|
|
247
|
+
const setContent: Write<(key: string, content: Content) => void> = (
|
|
248
|
+
transactors,
|
|
249
|
+
key,
|
|
250
|
+
content,
|
|
251
|
+
) => transactors.set(findContentState(key), content)
|
|
252
|
+
const deleteContent: Write<(key: string) => void> = (_, key) =>
|
|
253
|
+
dispose(findContentState(key))
|
|
254
|
+
const externalStoreWithContentConfiguration = {
|
|
292
255
|
getContent: (contentKey: string) => {
|
|
293
|
-
const content = getContent(
|
|
256
|
+
const content = getContent(this.transactors, contentKey)
|
|
294
257
|
return content
|
|
295
258
|
},
|
|
296
259
|
setContent: (contentKey: string, content: Content) => {
|
|
297
|
-
setContent(
|
|
260
|
+
setContent(this.transactors, contentKey, content)
|
|
298
261
|
},
|
|
299
262
|
deleteContent: (contentKey: string) => {
|
|
300
|
-
deleteContent(
|
|
263
|
+
deleteContent(this.transactors, contentKey)
|
|
301
264
|
},
|
|
302
265
|
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
266
|
+
externalStore = Object.assign(
|
|
267
|
+
baseExternalStoreConfiguration,
|
|
268
|
+
externalStoreWithContentConfiguration,
|
|
269
|
+
) as ExternalStoreConfiguration<Content>
|
|
270
|
+
} else {
|
|
271
|
+
externalStore =
|
|
272
|
+
baseExternalStoreConfiguration as ExternalStoreConfiguration<Content>
|
|
273
|
+
}
|
|
274
|
+
const relations = new Junction<ASide, BSide, Content>(options, {
|
|
275
|
+
externalStore,
|
|
276
|
+
makeContentKey: (...args) => args.sort().join(`:`),
|
|
277
|
+
})
|
|
315
278
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
279
|
+
const createSingleKeyStateFamily = () =>
|
|
280
|
+
createSelectorFamily<string | undefined, string>(
|
|
281
|
+
{
|
|
282
|
+
key: `${options.key}/singleRelatedKey`,
|
|
283
|
+
get:
|
|
284
|
+
(key) =>
|
|
285
|
+
({ get }) => {
|
|
286
|
+
const relatedKeys = get(findRelatedKeysState(key))
|
|
287
|
+
for (const relatedKey of relatedKeys) {
|
|
288
|
+
return relatedKey
|
|
289
|
+
}
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
store,
|
|
293
|
+
)
|
|
294
|
+
const getMultipleKeyStateFamily = () =>
|
|
295
|
+
getJsonFamily(findRelatedKeysState, store)
|
|
296
|
+
const createSingleEntryStateFamily = () =>
|
|
297
|
+
createSelectorFamily<[string, Content] | undefined, string>(
|
|
298
|
+
{
|
|
299
|
+
key: `${options.key}/singleRelatedEntry`,
|
|
300
|
+
get:
|
|
301
|
+
(key) =>
|
|
302
|
+
({ get }) => {
|
|
303
|
+
const relatedKeys = get(findRelatedKeysState(key))
|
|
304
|
+
for (const relatedKey of relatedKeys) {
|
|
305
|
+
const contentKey = relations.makeContentKey(key, relatedKey)
|
|
306
|
+
return [relatedKey, get(findContentState(contentKey))]
|
|
307
|
+
}
|
|
308
|
+
},
|
|
309
|
+
},
|
|
310
|
+
store,
|
|
311
|
+
)
|
|
312
|
+
const getMultipleEntryStateFamily = () =>
|
|
313
|
+
createSelectorFamily<[string, Content][], string>(
|
|
314
|
+
{
|
|
315
|
+
key: `${options.key}/multipleRelatedEntries`,
|
|
316
|
+
get:
|
|
317
|
+
(key) =>
|
|
318
|
+
({ get }) => {
|
|
319
|
+
const relatedKeys = get(findRelatedKeysState(key))
|
|
320
|
+
return [...relatedKeys].map((relatedKey) => {
|
|
321
|
+
const contentKey = relations.makeContentKey(key, relatedKey)
|
|
322
|
+
return [relatedKey, get(findContentState(contentKey))]
|
|
323
|
+
})
|
|
324
|
+
},
|
|
325
|
+
},
|
|
326
|
+
store,
|
|
327
|
+
)
|
|
365
328
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
329
|
+
switch (options.cardinality) {
|
|
330
|
+
case `1:1`: {
|
|
331
|
+
const findSingleRelatedKeyState = createSingleKeyStateFamily()
|
|
332
|
+
const stateKeyA = `${a}KeyOf${capitalize(b)}` as const
|
|
333
|
+
const stateKeyB = `${b}KeyOf${capitalize(a)}` as const
|
|
334
|
+
const findStateBase = {
|
|
335
|
+
[stateKeyA]: findSingleRelatedKeyState,
|
|
336
|
+
[stateKeyB]: findSingleRelatedKeyState,
|
|
337
|
+
} as JoinState<ASide, BSide, Cardinality, Content>
|
|
338
|
+
let findState: JoinState<ASide, BSide, Cardinality, Content>
|
|
339
|
+
if (defaultContent) {
|
|
340
|
+
const findSingleRelatedEntryState = createSingleEntryStateFamily()
|
|
341
|
+
const entriesStateKeyA = `${a}EntryOf${capitalize(b)}` as const
|
|
342
|
+
const entriesStateKeyB = `${b}EntryOf${capitalize(a)}` as const
|
|
343
|
+
const findStateWithContent = {
|
|
344
|
+
[entriesStateKeyA]: findSingleRelatedEntryState,
|
|
345
|
+
[entriesStateKeyB]: findSingleRelatedEntryState,
|
|
346
|
+
}
|
|
347
|
+
findState = Object.assign(findStateBase, findStateWithContent)
|
|
348
|
+
} else {
|
|
349
|
+
findState = findStateBase
|
|
383
350
|
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
}
|
|
388
|
-
return {
|
|
389
|
-
relations,
|
|
390
|
-
findState,
|
|
351
|
+
this.relations = relations
|
|
352
|
+
this.findState = findState
|
|
353
|
+
break
|
|
391
354
|
}
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
355
|
+
case `1:n`: {
|
|
356
|
+
const findSingleRelatedKeyState = createSingleKeyStateFamily()
|
|
357
|
+
const findMultipleRelatedKeysState = getMultipleKeyStateFamily()
|
|
358
|
+
const stateKeyA = `${a}KeyOf${capitalize(b)}` as const
|
|
359
|
+
const stateKeyB = `${b}KeysOf${capitalize(a)}` as const
|
|
360
|
+
const findStateBase = {
|
|
361
|
+
[stateKeyA]: findSingleRelatedKeyState,
|
|
362
|
+
[stateKeyB]: findMultipleRelatedKeysState,
|
|
363
|
+
} as JoinState<ASide, BSide, Cardinality, Content>
|
|
364
|
+
let findState: JoinState<ASide, BSide, Cardinality, Content>
|
|
365
|
+
if (defaultContent) {
|
|
366
|
+
const findSingleRelatedEntryState = createSingleEntryStateFamily()
|
|
367
|
+
const findMultipleRelatedEntriesState = getMultipleEntryStateFamily()
|
|
368
|
+
const entriesStateKeyA = `${a}EntryOf${capitalize(b)}` as const
|
|
369
|
+
const entriesStateKeyB = `${b}EntriesOf${capitalize(a)}` as const
|
|
370
|
+
const findStateWithContent = {
|
|
371
|
+
[entriesStateKeyA]: findSingleRelatedEntryState,
|
|
372
|
+
[entriesStateKeyB]: findMultipleRelatedEntriesState,
|
|
373
|
+
}
|
|
374
|
+
findState = Object.assign(findStateBase, findStateWithContent)
|
|
375
|
+
} else {
|
|
376
|
+
findState = findStateBase
|
|
411
377
|
}
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
378
|
+
this.relations = relations
|
|
379
|
+
this.findState = findState
|
|
380
|
+
break
|
|
415
381
|
}
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
[entriesStateKeyB]: findMultipleRelatedEntriesState,
|
|
382
|
+
default: {
|
|
383
|
+
const findMultipleRelatedKeysState = getMultipleKeyStateFamily()
|
|
384
|
+
const stateKeyA = `${a}KeysOf${capitalize(b)}` as const
|
|
385
|
+
const stateKeyB = `${b}KeysOf${capitalize(a)}` as const
|
|
386
|
+
const findStateBase = {
|
|
387
|
+
[stateKeyA]: findMultipleRelatedKeysState,
|
|
388
|
+
[stateKeyB]: findMultipleRelatedKeysState,
|
|
389
|
+
} as JoinState<ASide, BSide, Cardinality, Content>
|
|
390
|
+
let findState: JoinState<ASide, BSide, Cardinality, Content>
|
|
391
|
+
if (defaultContent) {
|
|
392
|
+
const findMultipleRelatedEntriesState = getMultipleEntryStateFamily()
|
|
393
|
+
const entriesStateKeyA = `${a}EntriesOf${capitalize(b)}` as const
|
|
394
|
+
const entriesStateKeyB = `${b}EntriesOf${capitalize(a)}` as const
|
|
395
|
+
const findStateWithContent = {
|
|
396
|
+
[entriesStateKeyA]: findMultipleRelatedEntriesState,
|
|
397
|
+
[entriesStateKeyB]: findMultipleRelatedEntriesState,
|
|
398
|
+
}
|
|
399
|
+
findState = Object.assign(findStateBase, findStateWithContent)
|
|
400
|
+
} else {
|
|
401
|
+
findState = findStateBase
|
|
437
402
|
}
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
findState = findStateBase
|
|
441
|
-
}
|
|
442
|
-
return {
|
|
443
|
-
relations,
|
|
444
|
-
findState,
|
|
403
|
+
this.relations = relations
|
|
404
|
+
this.findState = findState
|
|
445
405
|
}
|
|
446
406
|
}
|
|
447
|
-
default:
|
|
448
|
-
throw new Error(`Invalid cardinality: ${options.cardinality}`)
|
|
449
407
|
}
|
|
450
408
|
}
|
|
409
|
+
export function join<
|
|
410
|
+
const ASide extends string,
|
|
411
|
+
const BSide extends string,
|
|
412
|
+
const Cardinality extends `1:1` | `1:n` | `n:n`,
|
|
413
|
+
>(
|
|
414
|
+
options: JoinOptions<ASide, BSide, Cardinality, null>,
|
|
415
|
+
defaultContent?: undefined,
|
|
416
|
+
store?: Store,
|
|
417
|
+
): {
|
|
418
|
+
relations: Junction<ASide, BSide, null>
|
|
419
|
+
findState: JoinState<ASide, BSide, Cardinality, null>
|
|
420
|
+
transact: (
|
|
421
|
+
transactors: Transactors,
|
|
422
|
+
run: (join: Join<ASide, BSide, Cardinality, null>) => void,
|
|
423
|
+
) => void
|
|
424
|
+
}
|
|
425
|
+
export function join<
|
|
426
|
+
const ASide extends string,
|
|
427
|
+
const BSide extends string,
|
|
428
|
+
const Cardinality extends `1:1` | `1:n` | `n:n`,
|
|
429
|
+
const Content extends Json.Object,
|
|
430
|
+
>(
|
|
431
|
+
options: JoinOptions<ASide, BSide, Cardinality, Content>,
|
|
432
|
+
defaultContent: Content,
|
|
433
|
+
store?: Store,
|
|
434
|
+
): {
|
|
435
|
+
readonly relations: Junction<ASide, BSide, Content>
|
|
436
|
+
readonly findState: JoinState<ASide, BSide, Cardinality, Content>
|
|
437
|
+
readonly transact: (
|
|
438
|
+
transactors: Transactors,
|
|
439
|
+
run: (join: Join<ASide, BSide, Cardinality, Content>) => void,
|
|
440
|
+
) => void
|
|
441
|
+
}
|
|
442
|
+
export function join<
|
|
443
|
+
ASide extends string,
|
|
444
|
+
BSide extends string,
|
|
445
|
+
Cardinality extends `1:1` | `1:n` | `n:n`,
|
|
446
|
+
Content extends Json.Object,
|
|
447
|
+
>(
|
|
448
|
+
options: JoinOptions<ASide, BSide, Cardinality, Content>,
|
|
449
|
+
defaultContent: Content | undefined,
|
|
450
|
+
store: Store = IMPLICIT.STORE,
|
|
451
|
+
): Join<ASide, BSide, Cardinality, Content> {
|
|
452
|
+
return new Join(options, defaultContent, store)
|
|
453
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type * as AtomIO from "atom.io"
|
|
2
2
|
import {
|
|
3
3
|
IMPLICIT,
|
|
4
|
-
|
|
4
|
+
createRegularAtomFamily,
|
|
5
5
|
createSelectorFamily,
|
|
6
6
|
} from "atom.io/internal"
|
|
7
7
|
|
|
@@ -29,7 +29,7 @@ export function structFamily<
|
|
|
29
29
|
>}State`]: AtomIO.AtomFamily<Struct[K], string>
|
|
30
30
|
} = Object.keys(options.default).reduce((acc, subKey) => {
|
|
31
31
|
const atomFamilyName = nameFamily(options.key, subKey)
|
|
32
|
-
acc[atomFamilyName] =
|
|
32
|
+
acc[atomFamilyName] = createRegularAtomFamily(
|
|
33
33
|
{
|
|
34
34
|
key: `${options.key}.${subKey}`,
|
|
35
35
|
default: (options.default as any)[subKey],
|