atom.io 0.41.0 → 0.42.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/dist/internal/index.d.ts +21 -38
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +82 -263
- package/dist/internal/index.js.map +1 -1
- package/dist/main/index.d.ts +18 -36
- package/dist/main/index.d.ts.map +1 -1
- package/dist/main/index.js +13 -2
- package/dist/main/index.js.map +1 -1
- package/dist/realtime/index.d.ts +2 -3
- package/dist/realtime/index.d.ts.map +1 -1
- package/dist/realtime/index.js +1 -1
- package/dist/realtime/index.js.map +1 -1
- package/dist/realtime-server/index.js +1 -1
- package/dist/realtime-server/index.js.map +1 -1
- package/dist/realtime-testing/index.js +1 -1
- package/dist/struct/index.d.ts +14 -0
- package/dist/struct/index.d.ts.map +1 -0
- package/dist/struct/index.js +35 -0
- package/dist/struct/index.js.map +1 -0
- package/dist/transceivers/o-list/index.d.ts +10 -6
- package/dist/transceivers/o-list/index.d.ts.map +1 -1
- package/dist/transceivers/o-list/index.js +170 -169
- package/dist/transceivers/o-list/index.js.map +1 -1
- package/dist/transceivers/set-rtx/index.d.ts +1 -0
- package/dist/transceivers/set-rtx/index.d.ts.map +1 -1
- package/dist/transceivers/set-rtx/index.js.map +1 -1
- package/dist/transceivers/u-list/index.d.ts +10 -6
- package/dist/transceivers/u-list/index.d.ts.map +1 -1
- package/dist/transceivers/u-list/index.js +23 -22
- package/dist/transceivers/u-list/index.js.map +1 -1
- package/dist/utility-types-aZkJVERa.d.ts +10 -0
- package/dist/utility-types-aZkJVERa.d.ts.map +1 -0
- package/package.json +13 -9
- package/src/internal/index.ts +0 -1
- package/src/internal/join/create-join.ts +8 -11
- package/src/internal/join/edit-relations-in-store.ts +6 -8
- package/src/internal/join/find-relations-in-store.ts +11 -67
- package/src/internal/join/get-internal-relations-from-store.ts +11 -5
- package/src/internal/join/get-join.ts +7 -9
- package/src/internal/join/join-internal.ts +154 -394
- package/src/internal/mutable/transceiver.ts +1 -5
- package/src/internal/set-state/dispatch-state-update.ts +1 -1
- package/src/internal/store/store.ts +1 -1
- package/src/main/join.ts +68 -151
- package/src/main/realm.ts +4 -4
- package/src/realtime/shared-room-store.ts +5 -15
- package/src/realtime-server/realtime-server-stores/server-room-external-store.ts +1 -1
- package/src/struct/index.ts +1 -0
- package/src/{internal → struct}/micro.ts +1 -1
- package/src/transceivers/o-list/o-list.ts +175 -171
- package/src/transceivers/set-rtx/set-rtx.ts +4 -0
- package/src/transceivers/u-list/u-list.ts +37 -33
|
@@ -1,152 +1,83 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
CompoundTypedKey,
|
|
3
2
|
findState,
|
|
4
3
|
getState,
|
|
5
4
|
JoinOptions,
|
|
6
5
|
MutableAtomFamilyToken,
|
|
7
|
-
Read,
|
|
8
6
|
ReadonlyPureSelectorFamilyToken,
|
|
9
|
-
RegularAtomFamilyToken,
|
|
10
7
|
setState,
|
|
11
|
-
ViewOf,
|
|
12
8
|
Write,
|
|
13
9
|
WriterToolkit,
|
|
14
10
|
} from "atom.io"
|
|
15
11
|
import { Anarchy } from "atom.io"
|
|
16
|
-
import type { Json } from "atom.io/json"
|
|
17
12
|
import { stringifyJson } from "atom.io/json"
|
|
18
|
-
import {
|
|
13
|
+
import { UList } from "atom.io/transceivers/u-list"
|
|
19
14
|
|
|
20
15
|
import { capitalize } from "../capitalize"
|
|
21
|
-
import {
|
|
22
|
-
createReadonlyPureSelectorFamily,
|
|
23
|
-
createRegularAtomFamily,
|
|
24
|
-
findInStore,
|
|
25
|
-
} from "../families"
|
|
16
|
+
import { createReadonlyPureSelectorFamily, findInStore } from "../families"
|
|
26
17
|
import { getFromStore } from "../get-state"
|
|
27
|
-
import type {
|
|
28
|
-
BaseExternalStoreConfiguration,
|
|
29
|
-
ExternalStoreConfiguration,
|
|
30
|
-
} from "../junction"
|
|
18
|
+
import type { BaseExternalStoreConfiguration } from "../junction"
|
|
31
19
|
import { Junction } from "../junction"
|
|
32
20
|
import { createMutableAtomFamily, getJsonFamily, getJsonToken } from "../mutable"
|
|
33
|
-
import { setIntoStore } from "../set-state"
|
|
21
|
+
import { JOIN_OP, operateOnStore, setIntoStore } from "../set-state"
|
|
34
22
|
import type { Store } from "../store"
|
|
35
23
|
import { IMPLICIT } from "../store"
|
|
36
24
|
import type { RootStore } from "../transaction"
|
|
37
25
|
|
|
38
26
|
export type JoinStateFamilies<
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
27
|
+
AName extends string,
|
|
28
|
+
A extends string,
|
|
29
|
+
BName extends string,
|
|
30
|
+
B extends string,
|
|
43
31
|
Cardinality extends `1:1` | `1:n` | `n:n`,
|
|
44
|
-
Content extends Json.Object | null,
|
|
45
32
|
> = Cardinality extends `1:1`
|
|
46
|
-
?
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
BType
|
|
51
|
-
>
|
|
52
|
-
} & {
|
|
53
|
-
readonly [B in BSide as `${B}EntryOf${Capitalize<ASide>}`]: ReadonlyPureSelectorFamilyToken<
|
|
54
|
-
[BType, Content] | null,
|
|
55
|
-
AType
|
|
56
|
-
>
|
|
57
|
-
}
|
|
58
|
-
: {}) & {
|
|
59
|
-
readonly [A in ASide as `${A}KeyOf${Capitalize<BSide>}`]: ReadonlyPureSelectorFamilyToken<
|
|
60
|
-
AType | null,
|
|
61
|
-
BType
|
|
33
|
+
? {
|
|
34
|
+
readonly [N in AName as `${N}KeyOf${Capitalize<BName>}`]: ReadonlyPureSelectorFamilyToken<
|
|
35
|
+
A | null,
|
|
36
|
+
B
|
|
62
37
|
>
|
|
63
38
|
} & {
|
|
64
|
-
readonly [
|
|
65
|
-
|
|
66
|
-
|
|
39
|
+
readonly [N in BName as `${N}KeyOf${Capitalize<AName>}`]: ReadonlyPureSelectorFamilyToken<
|
|
40
|
+
B | null,
|
|
41
|
+
A
|
|
67
42
|
>
|
|
68
43
|
}
|
|
69
44
|
: Cardinality extends `1:n`
|
|
70
|
-
?
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
BType
|
|
75
|
-
>
|
|
76
|
-
} & {
|
|
77
|
-
readonly [B in BSide as `${B}EntriesOf${Capitalize<ASide>}`]: ReadonlyPureSelectorFamilyToken<
|
|
78
|
-
[BType, Content][],
|
|
79
|
-
AType
|
|
80
|
-
>
|
|
81
|
-
}
|
|
82
|
-
: {}) & {
|
|
83
|
-
readonly [A in ASide as `${A}KeyOf${Capitalize<BSide>}`]: ReadonlyPureSelectorFamilyToken<
|
|
84
|
-
AType | null,
|
|
85
|
-
BType
|
|
86
|
-
>
|
|
87
|
-
} & {
|
|
88
|
-
readonly [B in BSide as `${B}KeysOf${Capitalize<ASide>}`]: ReadonlyPureSelectorFamilyToken<
|
|
89
|
-
BType[],
|
|
90
|
-
AType
|
|
45
|
+
? {
|
|
46
|
+
readonly [N in BName as `${N}KeysOf${Capitalize<AName>}`]: ReadonlyPureSelectorFamilyToken<
|
|
47
|
+
B[],
|
|
48
|
+
A
|
|
91
49
|
>
|
|
92
50
|
}
|
|
93
51
|
: Cardinality extends `n:n`
|
|
94
|
-
?
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
BType
|
|
99
|
-
>
|
|
100
|
-
} & {
|
|
101
|
-
readonly [B in BSide as `${B}EntriesOf${Capitalize<ASide>}`]: ReadonlyPureSelectorFamilyToken<
|
|
102
|
-
[BType, Content][],
|
|
103
|
-
AType
|
|
104
|
-
>
|
|
105
|
-
}
|
|
106
|
-
: {}) & {
|
|
107
|
-
readonly [A in ASide as `${A}KeysOf${Capitalize<BSide>}`]: ReadonlyPureSelectorFamilyToken<
|
|
108
|
-
AType[],
|
|
109
|
-
BType
|
|
52
|
+
? {
|
|
53
|
+
readonly [N in AName as `${N}KeysOf${Capitalize<BName>}`]: ReadonlyPureSelectorFamilyToken<
|
|
54
|
+
A[],
|
|
55
|
+
B
|
|
110
56
|
>
|
|
111
57
|
} & {
|
|
112
|
-
readonly [
|
|
113
|
-
|
|
114
|
-
|
|
58
|
+
readonly [N in BName as `${N}KeysOf${Capitalize<AName>}`]: ReadonlyPureSelectorFamilyToken<
|
|
59
|
+
B[],
|
|
60
|
+
A
|
|
115
61
|
>
|
|
116
62
|
}
|
|
117
63
|
: never
|
|
118
64
|
|
|
119
65
|
export class Join<
|
|
120
|
-
const
|
|
121
|
-
const
|
|
122
|
-
const
|
|
123
|
-
const
|
|
66
|
+
const AName extends string,
|
|
67
|
+
const A extends string,
|
|
68
|
+
const BName extends string,
|
|
69
|
+
const B extends string,
|
|
124
70
|
const Cardinality extends `1:1` | `1:n` | `n:n`,
|
|
125
|
-
const Content extends Json.Object | null = null,
|
|
126
|
-
const ContentKey extends CompoundTypedKey<
|
|
127
|
-
`content`,
|
|
128
|
-
ASide,
|
|
129
|
-
BSide
|
|
130
|
-
> = CompoundTypedKey<`content`, ASide, BSide>,
|
|
131
71
|
> {
|
|
132
72
|
private toolkit: WriterToolkit
|
|
133
|
-
public options: JoinOptions<
|
|
134
|
-
public
|
|
135
|
-
public
|
|
136
|
-
public
|
|
137
|
-
|
|
138
|
-
AType,
|
|
139
|
-
BSide,
|
|
140
|
-
BType,
|
|
141
|
-
Cardinality,
|
|
142
|
-
Content
|
|
143
|
-
>
|
|
144
|
-
public core: {
|
|
145
|
-
relatedKeysAtoms: MutableAtomFamilyToken<SetRTX<string>, string>
|
|
146
|
-
}
|
|
73
|
+
public options: JoinOptions<AName, A, BName, B, Cardinality>
|
|
74
|
+
public relations: Junction<AName, A, BName, B>
|
|
75
|
+
public states: JoinStateFamilies<AName, A, BName, B, Cardinality>
|
|
76
|
+
public relatedKeysAtoms: MutableAtomFamilyToken<UList<string>, string>
|
|
77
|
+
|
|
147
78
|
public transact(
|
|
148
79
|
toolkit: WriterToolkit,
|
|
149
|
-
run: (join: Join<
|
|
80
|
+
run: (join: Join<AName, A, BName, B, Cardinality>) => void,
|
|
150
81
|
): void {
|
|
151
82
|
const originalToolkit = this.toolkit
|
|
152
83
|
this.toolkit = toolkit
|
|
@@ -160,16 +91,14 @@ export class Join<
|
|
|
160
91
|
public [Symbol.dispose](): void {}
|
|
161
92
|
|
|
162
93
|
public constructor(
|
|
163
|
-
options: JoinOptions<
|
|
164
|
-
defaultContent: Content | undefined,
|
|
94
|
+
options: JoinOptions<AName, A, BName, B, Cardinality>,
|
|
165
95
|
store: RootStore = IMPLICIT.STORE,
|
|
166
96
|
) {
|
|
167
|
-
type
|
|
97
|
+
type AB = A & B
|
|
168
98
|
|
|
169
99
|
this.store = store
|
|
170
100
|
this.realm = new Anarchy(store)
|
|
171
101
|
this.options = options
|
|
172
|
-
this.defaultContent = defaultContent
|
|
173
102
|
|
|
174
103
|
this.store.miscResources.set(`join:${options.key}`, this)
|
|
175
104
|
|
|
@@ -186,49 +115,18 @@ export class Join<
|
|
|
186
115
|
json: (token) => getJsonToken(store, token),
|
|
187
116
|
}
|
|
188
117
|
|
|
189
|
-
const aSide:
|
|
190
|
-
const bSide:
|
|
191
|
-
const relatedKeysAtoms = createMutableAtomFamily<
|
|
118
|
+
const aSide: AName = options.between[0]
|
|
119
|
+
const bSide: BName = options.between[1]
|
|
120
|
+
const relatedKeysAtoms = createMutableAtomFamily<UList<string>, string>(
|
|
192
121
|
store,
|
|
193
122
|
{
|
|
194
123
|
key: `${options.key}/relatedKeys`,
|
|
195
|
-
class:
|
|
124
|
+
class: UList,
|
|
196
125
|
},
|
|
197
126
|
[`join`, `relations`],
|
|
198
127
|
)
|
|
199
|
-
this.
|
|
200
|
-
|
|
201
|
-
(key: string) => SetRTX<AType> | SetRTX<BType>
|
|
202
|
-
> = ({ get }, key) =>
|
|
203
|
-
get(relatedKeysAtoms, key) as SetRTX<AType> | SetRTX<BType>
|
|
204
|
-
const addRelation: Write<(a: string, b: string) => void> = (
|
|
205
|
-
{ set },
|
|
206
|
-
a,
|
|
207
|
-
b,
|
|
208
|
-
) => {
|
|
209
|
-
if (!this.store.molecules.has(stringifyJson(a))) {
|
|
210
|
-
this.realm.allocate(options.key, a)
|
|
211
|
-
}
|
|
212
|
-
set(relatedKeysAtoms, a, (aKeys) => aKeys.add(b))
|
|
213
|
-
set(relatedKeysAtoms, b, (bKeys) => bKeys.add(a))
|
|
214
|
-
}
|
|
215
|
-
const deleteRelation: Write<(a: string, b: string) => void> = (
|
|
216
|
-
{ set },
|
|
217
|
-
a,
|
|
218
|
-
b,
|
|
219
|
-
) => {
|
|
220
|
-
set(relatedKeysAtoms, a, (aKeys) => {
|
|
221
|
-
aKeys.delete(b)
|
|
222
|
-
return aKeys
|
|
223
|
-
})
|
|
224
|
-
set(relatedKeysAtoms, b, (bKeys) => {
|
|
225
|
-
bKeys.delete(a)
|
|
226
|
-
return bKeys
|
|
227
|
-
})
|
|
228
|
-
const [x, y] = [a, b].sort()
|
|
229
|
-
const compositeKey = `${x}:${y}`
|
|
230
|
-
this.store.moleculeJoins.delete(compositeKey)
|
|
231
|
-
}
|
|
128
|
+
this.relatedKeysAtoms = relatedKeysAtoms
|
|
129
|
+
|
|
232
130
|
const replaceRelationsSafely: Write<
|
|
233
131
|
(a: string, newRelationsOfA: string[]) => void
|
|
234
132
|
> = (toolkit, a, newRelationsOfA) => {
|
|
@@ -246,42 +144,56 @@ export class Join<
|
|
|
246
144
|
})
|
|
247
145
|
}
|
|
248
146
|
set(relationsOfAState, (relationsOfA) => {
|
|
249
|
-
relationsOfA.transaction((nextRelationsOfA) => {
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
const previousOwnerRelations = getRelatedKeys(
|
|
261
|
-
toolkit,
|
|
262
|
-
previousOwner,
|
|
263
|
-
)
|
|
264
|
-
previousOwnerRelations.delete(newRelationB as AnyKey)
|
|
265
|
-
if (previousOwnerRelations.size === 0) {
|
|
266
|
-
previousOwnersToDispose.push(previousOwner)
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
if (!newRelationBIsAlreadyRelated && relationsOfB.size > 0) {
|
|
270
|
-
relationsOfB.clear()
|
|
147
|
+
// relationsOfA.transaction((nextRelationsOfA) => {
|
|
148
|
+
relationsOfA.clear()
|
|
149
|
+
for (const newRelationB of newRelationsOfA) {
|
|
150
|
+
const relationsOfBAtom = find(relatedKeysAtoms, newRelationB)
|
|
151
|
+
const relationsOfB = get(relationsOfBAtom)
|
|
152
|
+
const newRelationBIsAlreadyRelated = relationsOfB.has(a as AB)
|
|
153
|
+
if (this.relations.cardinality === `1:n`) {
|
|
154
|
+
const previousOwnersToDispose: string[] = []
|
|
155
|
+
for (const previousOwner of relationsOfB) {
|
|
156
|
+
if (previousOwner === a) {
|
|
157
|
+
continue
|
|
271
158
|
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
store
|
|
159
|
+
let previousOwnerSize: number | undefined
|
|
160
|
+
operateOnStore(
|
|
161
|
+
JOIN_OP,
|
|
162
|
+
this.store,
|
|
163
|
+
relatedKeysAtoms,
|
|
164
|
+
previousOwner,
|
|
165
|
+
(relations) => {
|
|
166
|
+
relations.delete(newRelationB as AB)
|
|
167
|
+
previousOwnerSize = relations.size
|
|
168
|
+
return relations
|
|
169
|
+
},
|
|
170
|
+
)
|
|
171
|
+
if (previousOwnerSize === 0) {
|
|
172
|
+
previousOwnersToDispose.push(previousOwner)
|
|
276
173
|
}
|
|
277
174
|
}
|
|
278
|
-
if (!newRelationBIsAlreadyRelated) {
|
|
279
|
-
|
|
175
|
+
if (!newRelationBIsAlreadyRelated && relationsOfB.size > 0) {
|
|
176
|
+
set(relationsOfBAtom, (relations) => {
|
|
177
|
+
relations.clear()
|
|
178
|
+
return relations
|
|
179
|
+
})
|
|
180
|
+
}
|
|
181
|
+
for (const previousOwner of previousOwnersToDispose) {
|
|
182
|
+
const [x, y] = [newRelationB, previousOwner].sort()
|
|
183
|
+
const compositeKey = `${x}:${y}`
|
|
184
|
+
store.moleculeJoins.delete(compositeKey)
|
|
280
185
|
}
|
|
281
|
-
nextRelationsOfA.add(newRelationB)
|
|
282
186
|
}
|
|
283
|
-
|
|
284
|
-
|
|
187
|
+
if (!newRelationBIsAlreadyRelated) {
|
|
188
|
+
set(relationsOfBAtom, (relations) => {
|
|
189
|
+
relations.add(a as AB)
|
|
190
|
+
return relations
|
|
191
|
+
})
|
|
192
|
+
}
|
|
193
|
+
relationsOfA.add(newRelationB)
|
|
194
|
+
}
|
|
195
|
+
// return true
|
|
196
|
+
// })
|
|
285
197
|
return relationsOfA
|
|
286
198
|
})
|
|
287
199
|
}
|
|
@@ -290,12 +202,12 @@ export class Join<
|
|
|
290
202
|
> = (toolkit, a, newRelationsOfA) => {
|
|
291
203
|
const { set } = toolkit
|
|
292
204
|
set(relatedKeysAtoms, a, (relationsOfA) => {
|
|
293
|
-
relationsOfA.transaction((nextRelationsOfA) => {
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
})
|
|
205
|
+
// relationsOfA.transaction((nextRelationsOfA) => {
|
|
206
|
+
for (const newRelationB of newRelationsOfA) {
|
|
207
|
+
relationsOfA.add(newRelationB)
|
|
208
|
+
}
|
|
209
|
+
// return true
|
|
210
|
+
// })
|
|
299
211
|
return relationsOfA
|
|
300
212
|
})
|
|
301
213
|
for (const newRelationB of newRelationsOfA) {
|
|
@@ -306,19 +218,33 @@ export class Join<
|
|
|
306
218
|
}
|
|
307
219
|
return true
|
|
308
220
|
}
|
|
309
|
-
const has: Read<(a: string, b?: string) => boolean> = (toolkit, a, b) => {
|
|
310
|
-
const aKeys = getRelatedKeys(toolkit, a)
|
|
311
|
-
return b ? aKeys.has(b as AnyKey) : aKeys.size > 0
|
|
312
|
-
}
|
|
313
221
|
const baseExternalStoreConfiguration: BaseExternalStoreConfiguration = {
|
|
314
|
-
getRelatedKeys: (key) =>
|
|
222
|
+
getRelatedKeys: (key) =>
|
|
223
|
+
this.toolkit.get(relatedKeysAtoms, key) as UList<A> | UList<B>,
|
|
315
224
|
addRelation: (a, b) => {
|
|
316
225
|
this.store.moleculeJoins.set(`"${a}"`, options.key)
|
|
317
226
|
this.store.moleculeJoins.set(`"${b}"`, options.key)
|
|
318
|
-
|
|
227
|
+
if (!this.store.molecules.has(stringifyJson(a))) {
|
|
228
|
+
this.realm.allocate(options.key, a)
|
|
229
|
+
}
|
|
230
|
+
if (!this.store.molecules.has(stringifyJson(b))) {
|
|
231
|
+
this.realm.allocate(options.key, b)
|
|
232
|
+
}
|
|
233
|
+
this.toolkit.set(relatedKeysAtoms, a, (aKeys) => aKeys.add(b))
|
|
234
|
+
this.toolkit.set(relatedKeysAtoms, b, (bKeys) => bKeys.add(a))
|
|
319
235
|
},
|
|
320
236
|
deleteRelation: (a, b) => {
|
|
321
|
-
|
|
237
|
+
this.toolkit.set(relatedKeysAtoms, a, (aKeys) => {
|
|
238
|
+
aKeys.delete(b)
|
|
239
|
+
return aKeys
|
|
240
|
+
})
|
|
241
|
+
this.toolkit.set(relatedKeysAtoms, b, (bKeys) => {
|
|
242
|
+
bKeys.delete(a)
|
|
243
|
+
return bKeys
|
|
244
|
+
})
|
|
245
|
+
const [x, y] = [a, b].sort()
|
|
246
|
+
const compositeKey = `${x}:${y}`
|
|
247
|
+
this.store.moleculeJoins.delete(compositeKey)
|
|
322
248
|
},
|
|
323
249
|
replaceRelationsSafely: (a, bs) => {
|
|
324
250
|
replaceRelationsSafely(this.toolkit, a, bs)
|
|
@@ -326,77 +252,35 @@ export class Join<
|
|
|
326
252
|
replaceRelationsUnsafely: (a, bs) => {
|
|
327
253
|
replaceRelationsUnsafely(this.toolkit, a, bs)
|
|
328
254
|
},
|
|
329
|
-
has: (a, b) =>
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
if (defaultContent) {
|
|
335
|
-
contentAtoms = createRegularAtomFamily<Content, ContentKey, never>(
|
|
336
|
-
store,
|
|
337
|
-
{
|
|
338
|
-
key: `${options.key}/content`,
|
|
339
|
-
default: defaultContent,
|
|
340
|
-
},
|
|
341
|
-
[`join`, `content`],
|
|
342
|
-
)
|
|
343
|
-
|
|
344
|
-
const getContent: Read<(key: string) => ViewOf<Content> | null> = (
|
|
345
|
-
{ get },
|
|
346
|
-
key,
|
|
347
|
-
) => get(contentAtoms, key)
|
|
348
|
-
const setContent: Write<(key: string, content: Content) => void> = (
|
|
349
|
-
{ set },
|
|
350
|
-
key,
|
|
351
|
-
content,
|
|
352
|
-
) => {
|
|
353
|
-
set(contentAtoms, key, content)
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
const externalStoreWithContentConfiguration = {
|
|
357
|
-
getContent: (contentKey: ContentKey) => {
|
|
358
|
-
const content = getContent(this.toolkit, contentKey)
|
|
359
|
-
return content
|
|
360
|
-
},
|
|
361
|
-
setContent: (contentKey: ContentKey, content: Content) => {
|
|
362
|
-
setContent(this.toolkit, contentKey, content)
|
|
363
|
-
},
|
|
364
|
-
deleteContent: (_: ContentKey) => {},
|
|
365
|
-
}
|
|
366
|
-
externalStore = Object.assign(
|
|
367
|
-
baseExternalStoreConfiguration,
|
|
368
|
-
externalStoreWithContentConfiguration,
|
|
369
|
-
) as ExternalStoreConfiguration<Content>
|
|
370
|
-
} else {
|
|
371
|
-
externalStore =
|
|
372
|
-
baseExternalStoreConfiguration as ExternalStoreConfiguration<Content>
|
|
255
|
+
has: (a, b) => {
|
|
256
|
+
const aKeys = this.toolkit.get(relatedKeysAtoms, a)
|
|
257
|
+
return b ? aKeys.has(b as AB) : aKeys.size > 0
|
|
258
|
+
},
|
|
373
259
|
}
|
|
374
|
-
const
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
}
|
|
260
|
+
const externalStore = baseExternalStoreConfiguration
|
|
261
|
+
const relations = new Junction<AName, A, BName, B>(options as any, {
|
|
262
|
+
externalStore,
|
|
263
|
+
isAType: options.isAType,
|
|
264
|
+
isBType: options.isBType,
|
|
265
|
+
// makeContentKey: (...args) => {
|
|
266
|
+
// const [a, b] = args
|
|
267
|
+
// const [x, y] = args.sort()
|
|
268
|
+
// const compositeKey = `${x}:${y}`
|
|
269
|
+
// const aMolecule = store.molecules.get(stringifyJson(a))
|
|
270
|
+
// const bMolecule = store.molecules.get(stringifyJson(b))
|
|
271
|
+
// if (!aMolecule) {
|
|
272
|
+
// this.realm.allocate(options.key, a)
|
|
273
|
+
// }
|
|
274
|
+
// if (!bMolecule) {
|
|
275
|
+
// this.realm.allocate(options.key, b)
|
|
276
|
+
// }
|
|
392
277
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
)
|
|
278
|
+
// this.realm.allocate(a, compositeKey, `all`)
|
|
279
|
+
// this.realm.claim(b, compositeKey)
|
|
280
|
+
// this.store.moleculeJoins.set(compositeKey, options.key)
|
|
281
|
+
// return compositeKey
|
|
282
|
+
// },
|
|
283
|
+
})
|
|
400
284
|
|
|
401
285
|
const createSingleKeySelectorFamily = () =>
|
|
402
286
|
createReadonlyPureSelectorFamily<string | null, string, never>(
|
|
@@ -416,7 +300,7 @@ export class Join<
|
|
|
416
300
|
[`join`, `keys`],
|
|
417
301
|
)
|
|
418
302
|
const getMultipleKeySelectorFamily = () => {
|
|
419
|
-
return createReadonlyPureSelectorFamily<string[], string, never>(
|
|
303
|
+
return createReadonlyPureSelectorFamily<readonly string[], string, never>(
|
|
420
304
|
store,
|
|
421
305
|
{
|
|
422
306
|
key: `${options.key}/multipleRelatedKeys`,
|
|
@@ -425,98 +309,23 @@ export class Join<
|
|
|
425
309
|
({ get }) => {
|
|
426
310
|
const jsonFamily = getJsonFamily(relatedKeysAtoms, store)
|
|
427
311
|
const json = get(jsonFamily, key)
|
|
428
|
-
return json
|
|
312
|
+
return json
|
|
429
313
|
},
|
|
430
314
|
},
|
|
431
315
|
[`join`, `keys`],
|
|
432
316
|
)
|
|
433
317
|
}
|
|
434
|
-
const createSingleEntrySelectorFamily = () =>
|
|
435
|
-
createReadonlyPureSelectorFamily<
|
|
436
|
-
[string, ViewOf<Content>] | null,
|
|
437
|
-
string,
|
|
438
|
-
never
|
|
439
|
-
>(
|
|
440
|
-
store,
|
|
441
|
-
{
|
|
442
|
-
key: `${options.key}/singleRelatedEntry`,
|
|
443
|
-
get:
|
|
444
|
-
(x) =>
|
|
445
|
-
({ get }) => {
|
|
446
|
-
const relatedKeys = get(relatedKeysAtoms, x)
|
|
447
|
-
for (const y of relatedKeys) {
|
|
448
|
-
let a = relations.isAType?.(x) ? x : undefined
|
|
449
|
-
let b = a === undefined ? (x as BType) : undefined
|
|
450
|
-
a ??= y as AType
|
|
451
|
-
b ??= y as BType
|
|
452
|
-
const contentKey = relations.makeContentKey(a, b)
|
|
453
|
-
const content = get(contentAtoms, contentKey)
|
|
454
|
-
return [y, content]
|
|
455
|
-
}
|
|
456
|
-
return null
|
|
457
|
-
},
|
|
458
|
-
},
|
|
459
|
-
[`join`, `entries`],
|
|
460
|
-
)
|
|
461
|
-
const getMultipleEntrySelectorFamily = () =>
|
|
462
|
-
createReadonlyPureSelectorFamily<
|
|
463
|
-
[string, ViewOf<Content>][],
|
|
464
|
-
string,
|
|
465
|
-
never
|
|
466
|
-
>(
|
|
467
|
-
store,
|
|
468
|
-
{
|
|
469
|
-
key: `${options.key}/multipleRelatedEntries`,
|
|
470
|
-
get:
|
|
471
|
-
(x) =>
|
|
472
|
-
({ get }) => {
|
|
473
|
-
const jsonFamily = getJsonFamily(relatedKeysAtoms, store)
|
|
474
|
-
const json = get(jsonFamily, x)
|
|
475
|
-
return json.members.map((y) => {
|
|
476
|
-
let a = relations.isAType?.(x) ? x : undefined
|
|
477
|
-
let b = a === undefined ? (x as BType) : undefined
|
|
478
|
-
a ??= y as AType
|
|
479
|
-
b ??= y as BType
|
|
480
|
-
const contentKey = relations.makeContentKey(a, b)
|
|
481
|
-
const content = get(contentAtoms, contentKey)
|
|
482
|
-
return [y, content]
|
|
483
|
-
})
|
|
484
|
-
},
|
|
485
|
-
},
|
|
486
|
-
[`join`, `entries`],
|
|
487
|
-
)
|
|
488
318
|
|
|
489
319
|
switch (options.cardinality) {
|
|
490
320
|
case `1:1`: {
|
|
491
321
|
const singleRelatedKeySelectors = createSingleKeySelectorFamily()
|
|
492
322
|
const stateKeyA = `${aSide}KeyOf${capitalize(bSide)}` as const
|
|
493
323
|
const stateKeyB = `${bSide}KeyOf${capitalize(aSide)}` as const
|
|
494
|
-
|
|
324
|
+
this.relations = relations
|
|
325
|
+
this.states = {
|
|
495
326
|
[stateKeyA]: singleRelatedKeySelectors,
|
|
496
327
|
[stateKeyB]: singleRelatedKeySelectors,
|
|
497
|
-
} as JoinStateFamilies<
|
|
498
|
-
let states: JoinStateFamilies<
|
|
499
|
-
ASide,
|
|
500
|
-
AType,
|
|
501
|
-
BSide,
|
|
502
|
-
BType,
|
|
503
|
-
Cardinality,
|
|
504
|
-
Content
|
|
505
|
-
>
|
|
506
|
-
if (defaultContent) {
|
|
507
|
-
const singleEntrySelectors = createSingleEntrySelectorFamily()
|
|
508
|
-
const entriesStateKeyA = `${aSide}EntryOf${capitalize(bSide)}` as const
|
|
509
|
-
const entriesStateKeyB = `${bSide}EntryOf${capitalize(aSide)}` as const
|
|
510
|
-
const contentStates = {
|
|
511
|
-
[entriesStateKeyA]: singleEntrySelectors,
|
|
512
|
-
[entriesStateKeyB]: singleEntrySelectors,
|
|
513
|
-
}
|
|
514
|
-
states = Object.assign(baseStates, contentStates)
|
|
515
|
-
} else {
|
|
516
|
-
states = baseStates
|
|
517
|
-
}
|
|
518
|
-
this.relations = relations
|
|
519
|
-
this.states = states
|
|
328
|
+
} as JoinStateFamilies<AName, A, BName, B, Cardinality>
|
|
520
329
|
break
|
|
521
330
|
}
|
|
522
331
|
case `1:n`: {
|
|
@@ -527,70 +336,21 @@ export class Join<
|
|
|
527
336
|
const baseStates = {
|
|
528
337
|
[stateKeyA]: singleRelatedKeySelectors,
|
|
529
338
|
[stateKeyB]: multipleRelatedKeysSelectors,
|
|
530
|
-
} as JoinStateFamilies<
|
|
531
|
-
|
|
532
|
-
ASide,
|
|
533
|
-
AType,
|
|
534
|
-
BSide,
|
|
535
|
-
BType,
|
|
536
|
-
Cardinality,
|
|
537
|
-
Content
|
|
538
|
-
>
|
|
539
|
-
if (defaultContent) {
|
|
540
|
-
const singleRelatedEntrySelectors = createSingleEntrySelectorFamily()
|
|
541
|
-
const multipleRelatedEntriesSelectors =
|
|
542
|
-
getMultipleEntrySelectorFamily()
|
|
543
|
-
const entriesStateKeyA = `${aSide}EntryOf${capitalize(bSide)}` as const
|
|
544
|
-
const entriesStateKeyB = `${bSide}EntriesOf${capitalize(
|
|
545
|
-
aSide,
|
|
546
|
-
)}` as const
|
|
547
|
-
const contentStates = {
|
|
548
|
-
[entriesStateKeyA]: singleRelatedEntrySelectors,
|
|
549
|
-
[entriesStateKeyB]: multipleRelatedEntriesSelectors,
|
|
550
|
-
}
|
|
551
|
-
states = Object.assign(baseStates, contentStates)
|
|
552
|
-
} else {
|
|
553
|
-
states = baseStates
|
|
554
|
-
}
|
|
339
|
+
} as JoinStateFamilies<AName, A, BName, B, Cardinality>
|
|
340
|
+
|
|
555
341
|
this.relations = relations
|
|
556
|
-
this.states =
|
|
342
|
+
this.states = baseStates
|
|
557
343
|
break
|
|
558
344
|
}
|
|
559
345
|
case `n:n`: {
|
|
560
346
|
const multipleRelatedKeysSelectors = getMultipleKeySelectorFamily()
|
|
561
347
|
const stateKeyA = `${aSide}KeysOf${capitalize(bSide)}` as const
|
|
562
348
|
const stateKeyB = `${bSide}KeysOf${capitalize(aSide)}` as const
|
|
563
|
-
|
|
349
|
+
this.relations = relations
|
|
350
|
+
this.states = {
|
|
564
351
|
[stateKeyA]: multipleRelatedKeysSelectors,
|
|
565
352
|
[stateKeyB]: multipleRelatedKeysSelectors,
|
|
566
|
-
} as JoinStateFamilies<
|
|
567
|
-
let states: JoinStateFamilies<
|
|
568
|
-
ASide,
|
|
569
|
-
AType,
|
|
570
|
-
BSide,
|
|
571
|
-
BType,
|
|
572
|
-
Cardinality,
|
|
573
|
-
Content
|
|
574
|
-
>
|
|
575
|
-
if (defaultContent) {
|
|
576
|
-
const multipleRelatedEntriesSelectors =
|
|
577
|
-
getMultipleEntrySelectorFamily()
|
|
578
|
-
const entriesStateKeyA = `${aSide}EntriesOf${capitalize(
|
|
579
|
-
bSide,
|
|
580
|
-
)}` as const
|
|
581
|
-
const entriesStateKeyB = `${bSide}EntriesOf${capitalize(
|
|
582
|
-
aSide,
|
|
583
|
-
)}` as const
|
|
584
|
-
const contentStates = {
|
|
585
|
-
[entriesStateKeyA]: multipleRelatedEntriesSelectors,
|
|
586
|
-
[entriesStateKeyB]: multipleRelatedEntriesSelectors,
|
|
587
|
-
}
|
|
588
|
-
states = Object.assign(baseStates, contentStates)
|
|
589
|
-
} else {
|
|
590
|
-
states = baseStates
|
|
591
|
-
}
|
|
592
|
-
this.relations = relations
|
|
593
|
-
this.states = states
|
|
353
|
+
} as JoinStateFamilies<AName, A, BName, B, Cardinality>
|
|
594
354
|
}
|
|
595
355
|
}
|
|
596
356
|
}
|