atom.io 0.44.14 → 0.45.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/eslint-plugin/index.js +1 -1
- package/dist/introspection/index.d.ts +3 -2
- package/dist/introspection/index.d.ts.map +1 -1
- package/dist/introspection/index.js.map +1 -1
- package/dist/json/index.d.ts +34 -20
- package/dist/json/index.d.ts.map +1 -1
- package/dist/json/index.js +40 -2
- package/dist/json/index.js.map +1 -1
- package/dist/main/index.d.ts +3 -3
- package/dist/main/index.d.ts.map +1 -1
- package/dist/main/index.js +3 -2
- package/dist/main/index.js.map +1 -1
- package/dist/react/index.d.ts +4 -4
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js.map +1 -1
- package/dist/react-devtools/index.js.map +1 -1
- package/dist/realtime-client/index.d.ts +1 -1
- package/dist/realtime-client/index.d.ts.map +1 -1
- package/dist/realtime-client/index.js.map +1 -1
- package/dist/realtime-server/index.d.ts +5 -0
- package/dist/realtime-server/index.d.ts.map +1 -1
- package/dist/realtime-server/index.js +38 -12
- package/dist/realtime-server/index.js.map +1 -1
- package/dist/realtime-testing/index.d.ts.map +1 -1
- package/dist/realtime-testing/index.js +3 -9
- package/dist/realtime-testing/index.js.map +1 -1
- package/dist/transceivers/o-list/index.d.ts +1 -2
- package/dist/transceivers/o-list/index.d.ts.map +1 -1
- package/dist/transceivers/o-list/index.js +23 -24
- package/dist/transceivers/o-list/index.js.map +1 -1
- package/dist/transceivers/u-list/index.d.ts +1 -2
- package/dist/transceivers/u-list/index.d.ts.map +1 -1
- package/dist/transceivers/u-list/index.js +5 -6
- package/dist/transceivers/u-list/index.js.map +1 -1
- package/package.json +2 -10
- package/src/introspection/attach-introspection-states.ts +1 -1
- package/src/introspection/attach-transaction-logs.ts +2 -2
- package/src/introspection/index.ts +3 -0
- package/src/json/canonical.ts +42 -0
- package/src/json/enumeration.ts +36 -0
- package/src/json/index.ts +3 -132
- package/src/json/json.ts +128 -0
- package/src/main/index.ts +9 -2
- package/src/main/logger.ts +4 -2
- package/src/react/use-loadable.ts +10 -5
- package/src/react-devtools/TransactionIndex.tsx +1 -1
- package/src/react-devtools/store.ts +3 -3
- package/src/realtime-client/continuity/register-and-attempt-confirmed-update.ts +2 -2
- package/src/realtime-server/realtime-family-provider.ts +44 -0
- package/src/realtime-server/realtime-mutable-family-provider.ts +38 -0
- package/src/realtime-server/realtime-mutable-provider.ts +19 -0
- package/src/realtime-server/realtime-server-stores/provide-rooms.ts +2 -1
- package/src/realtime-server/realtime-state-provider.ts +20 -0
- package/src/realtime-server/server-config.ts +2 -1
- package/src/realtime-testing/setup-realtime-test.tsx +3 -9
- package/src/transceivers/o-list/o-list.ts +27 -28
- package/src/transceivers/u-list/u-list.ts +7 -8
- package/dist/data/index.d.ts +0 -23
- package/dist/data/index.d.ts.map +0 -1
- package/dist/data/index.js +0 -63
- package/dist/data/index.js.map +0 -1
- package/dist/struct/index.d.ts +0 -14
- package/dist/struct/index.d.ts.map +0 -1
- package/dist/struct/index.js +0 -37
- package/dist/struct/index.js.map +0 -1
- package/src/data/dict.ts +0 -31
- package/src/data/index.ts +0 -3
- package/src/data/struct-family.ts +0 -53
- package/src/data/struct.ts +0 -54
- package/src/struct/index.ts +0 -1
- package/src/struct/micro.ts +0 -72
- /package/dist/{chunk-D8lmAICg.js → chunk-CKcAJnC7.js} +0 -0
package/src/json/index.ts
CHANGED
|
@@ -1,133 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export * from "./canonical"
|
|
3
2
|
export * from "./entries"
|
|
4
|
-
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
export namespace Json {
|
|
8
|
-
export namespace Tree {
|
|
9
|
-
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
10
|
-
export type Array<Element = unknown> = ReadonlyArray<Element>
|
|
11
|
-
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
12
|
-
export type Object<K extends string = string, V = unknown> = Record<K, V>
|
|
13
|
-
export type Fork = Array | Object
|
|
14
|
-
export type Leaf = primitive
|
|
15
|
-
export type Node = Fork | Leaf
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/** A value can survive being {@link JSON.stringify}-ed and {@link JSON.parse}-d fully intact */
|
|
19
|
-
export type Serializable =
|
|
20
|
-
| primitive
|
|
21
|
-
| Readonly<{ [key: string]: Serializable }>
|
|
22
|
-
| ReadonlyArray<Serializable>
|
|
23
|
-
|
|
24
|
-
export type Object<
|
|
25
|
-
Key extends string = string,
|
|
26
|
-
Value extends Serializable = Serializable,
|
|
27
|
-
> = Record<Key, Value>
|
|
28
|
-
|
|
29
|
-
export type Array<Element extends Serializable = Serializable> =
|
|
30
|
-
ReadonlyArray<Element>
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/** A generic that retains the type information of a {@link Json.Serializable} value while in string form */
|
|
34
|
-
// biome-ignore format: long silly ternary
|
|
35
|
-
export type stringified<J extends Json.Serializable> = (
|
|
36
|
-
J extends string
|
|
37
|
-
? `"${J}"`
|
|
38
|
-
: J extends number
|
|
39
|
-
? `${J}`
|
|
40
|
-
: J extends true
|
|
41
|
-
? `true`
|
|
42
|
-
: J extends false
|
|
43
|
-
? `false`
|
|
44
|
-
: J extends boolean
|
|
45
|
-
? `false` | `true`
|
|
46
|
-
: J extends null
|
|
47
|
-
? `null`
|
|
48
|
-
: J extends []
|
|
49
|
-
? `[]`
|
|
50
|
-
: J extends [infer Element extends Json.Serializable]
|
|
51
|
-
? `[${stringified<Element>}]`
|
|
52
|
-
: J extends [
|
|
53
|
-
infer Element1 extends Json.Serializable,
|
|
54
|
-
infer Element2 extends Json.Serializable,
|
|
55
|
-
]
|
|
56
|
-
? `[${stringified<Element1>}, ${stringified<Element2>}]`
|
|
57
|
-
: J extends [
|
|
58
|
-
infer Element1 extends Json.Serializable,
|
|
59
|
-
infer Element2 extends Json.Serializable,
|
|
60
|
-
infer Element3 extends Json.Serializable,
|
|
61
|
-
]
|
|
62
|
-
? `[${stringified<Element1>}, ${stringified<Element2>}, ${stringified<Element3>}]`
|
|
63
|
-
: J extends any[]
|
|
64
|
-
? `[${string}]` & { __json?: J }
|
|
65
|
-
: string & { __json?: J }
|
|
66
|
-
)
|
|
67
|
-
|
|
68
|
-
/** Type-safe wrapper for {@link JSON.parse} */
|
|
69
|
-
export function parseJson<J extends Json.Serializable>(str: stringified<J>): J
|
|
70
|
-
/** Type-safe wrapper for {@link JSON.parse} */
|
|
71
|
-
export function parseJson(str: string): Json.Serializable
|
|
72
|
-
export function parseJson(str: string): Json.Serializable {
|
|
73
|
-
return JSON.parse(str)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/** Type-safe wrapper for {@link JSON.stringify} */
|
|
77
|
-
export const stringifyJson = <J extends Json.Serializable>(
|
|
78
|
-
json: J,
|
|
79
|
-
): stringified<J> => JSON.stringify(json) as stringified<J>
|
|
80
|
-
|
|
81
|
-
/** Only Canonical values should be used for keys because they always serialize to the same string */
|
|
82
|
-
export type Canonical = primitive | ReadonlyArray<Canonical>
|
|
83
|
-
|
|
84
|
-
/** A function whose parameters and return value are {@link Json.Serializable} */
|
|
85
|
-
export type JsonIO = (...params: Json.Serializable[]) => Json.Serializable | void
|
|
86
|
-
|
|
87
|
-
export type JsonInterface<T, J extends Json.Serializable = Json.Serializable> = {
|
|
88
|
-
toJson: (t: ViewOf<T>) => J
|
|
89
|
-
fromJson: (json: J) => T
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const JSON_PROTOTYPES = [
|
|
93
|
-
Array.prototype,
|
|
94
|
-
Boolean.prototype,
|
|
95
|
-
Number.prototype,
|
|
96
|
-
Object.prototype,
|
|
97
|
-
String.prototype,
|
|
98
|
-
] as const
|
|
99
|
-
export const isJson = (input: unknown): input is Json.Tree.Node => {
|
|
100
|
-
if (input === null) return true
|
|
101
|
-
if (input === undefined) return false
|
|
102
|
-
const prototype = Object.getPrototypeOf(input)
|
|
103
|
-
return JSON_PROTOTYPES.includes(prototype)
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export const JSON_TYPE_NAMES = [
|
|
107
|
-
`array`,
|
|
108
|
-
`boolean`,
|
|
109
|
-
`null`,
|
|
110
|
-
`number`,
|
|
111
|
-
`object`,
|
|
112
|
-
`string`,
|
|
113
|
-
] as const
|
|
114
|
-
|
|
115
|
-
export type JsonTypeName = (typeof JSON_TYPE_NAMES)[number]
|
|
116
|
-
|
|
117
|
-
export interface JsonTypes extends Record<JsonTypeName, Json.Serializable> {
|
|
118
|
-
array: Json.Array
|
|
119
|
-
boolean: boolean
|
|
120
|
-
null: null
|
|
121
|
-
number: number
|
|
122
|
-
object: Json.Object
|
|
123
|
-
string: string
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
export const JSON_DEFAULTS: JsonTypes = {
|
|
127
|
-
array: [],
|
|
128
|
-
boolean: false,
|
|
129
|
-
null: null,
|
|
130
|
-
number: 0,
|
|
131
|
-
object: {},
|
|
132
|
-
string: ``,
|
|
133
|
-
}
|
|
3
|
+
export * from "./enumeration"
|
|
4
|
+
export * from "./json"
|
package/src/json/json.ts
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import type { ViewOf } from "atom.io"
|
|
2
|
+
|
|
3
|
+
export type primitive = boolean | number | string | null
|
|
4
|
+
|
|
5
|
+
export namespace Json {
|
|
6
|
+
export namespace Tree {
|
|
7
|
+
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
8
|
+
export type Array<Element = unknown> = ReadonlyArray<Element>
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
10
|
+
export type Object<K extends string = string, V = unknown> = Record<K, V>
|
|
11
|
+
export type Fork = Array | Object
|
|
12
|
+
export type Leaf = primitive
|
|
13
|
+
export type Node = Fork | Leaf
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** A value can survive being {@link JSON.stringify}-ed and {@link JSON.parse}-d fully intact */
|
|
17
|
+
export type Serializable =
|
|
18
|
+
| primitive
|
|
19
|
+
| Readonly<{ [key: string]: Serializable }>
|
|
20
|
+
| ReadonlyArray<Serializable>
|
|
21
|
+
|
|
22
|
+
export type Object<
|
|
23
|
+
Key extends string = string,
|
|
24
|
+
Value extends Serializable = Serializable,
|
|
25
|
+
> = Record<Key, Value>
|
|
26
|
+
|
|
27
|
+
export type Array<Element extends Serializable = Serializable> =
|
|
28
|
+
ReadonlyArray<Element>
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** A generic that retains the type information of a {@link Json.Serializable} value while in string form */
|
|
32
|
+
// biome-ignore format: long silly ternary
|
|
33
|
+
export type stringified<J extends Json.Serializable> = (
|
|
34
|
+
J extends string
|
|
35
|
+
? `"${J}"`
|
|
36
|
+
: J extends number
|
|
37
|
+
? `${J}`
|
|
38
|
+
: J extends true
|
|
39
|
+
? `true`
|
|
40
|
+
: J extends false
|
|
41
|
+
? `false`
|
|
42
|
+
: J extends boolean
|
|
43
|
+
? `false` | `true`
|
|
44
|
+
: J extends null
|
|
45
|
+
? `null`
|
|
46
|
+
: J extends []
|
|
47
|
+
? `[]`
|
|
48
|
+
: J extends [infer Element extends Json.Serializable]
|
|
49
|
+
? `[${stringified<Element>}]`
|
|
50
|
+
: J extends [
|
|
51
|
+
infer Element1 extends Json.Serializable,
|
|
52
|
+
infer Element2 extends Json.Serializable,
|
|
53
|
+
]
|
|
54
|
+
? `[${stringified<Element1>}, ${stringified<Element2>}]`
|
|
55
|
+
: J extends [
|
|
56
|
+
infer Element1 extends Json.Serializable,
|
|
57
|
+
infer Element2 extends Json.Serializable,
|
|
58
|
+
infer Element3 extends Json.Serializable,
|
|
59
|
+
]
|
|
60
|
+
? `[${stringified<Element1>}, ${stringified<Element2>}, ${stringified<Element3>}]`
|
|
61
|
+
: J extends any[]
|
|
62
|
+
? `[${string}]` & { __json?: J }
|
|
63
|
+
: string & { __json?: J }
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
/** Type-safe wrapper for {@link JSON.parse} */
|
|
67
|
+
export function parseJson<J extends Json.Serializable>(str: stringified<J>): J
|
|
68
|
+
/** Type-safe wrapper for {@link JSON.parse} */
|
|
69
|
+
export function parseJson(str: string): Json.Serializable
|
|
70
|
+
export function parseJson(str: string): Json.Serializable {
|
|
71
|
+
return JSON.parse(str)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Type-safe wrapper for {@link JSON.stringify} */
|
|
75
|
+
export const stringifyJson = <J extends Json.Serializable>(
|
|
76
|
+
json: J,
|
|
77
|
+
): stringified<J> => JSON.stringify(json) as stringified<J>
|
|
78
|
+
|
|
79
|
+
/** A function whose parameters and return value are {@link Json.Serializable} */
|
|
80
|
+
export type JsonIO = (...params: Json.Serializable[]) => Json.Serializable | void
|
|
81
|
+
|
|
82
|
+
export type JsonInterface<T, J extends Json.Serializable = Json.Serializable> = {
|
|
83
|
+
toJson: (t: ViewOf<T>) => J
|
|
84
|
+
fromJson: (json: J) => T
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const JSON_PROTOTYPES = [
|
|
88
|
+
Array.prototype,
|
|
89
|
+
Boolean.prototype,
|
|
90
|
+
Number.prototype,
|
|
91
|
+
Object.prototype,
|
|
92
|
+
String.prototype,
|
|
93
|
+
] as const
|
|
94
|
+
export const isJson = (input: unknown): input is Json.Tree.Node => {
|
|
95
|
+
if (input === null) return true
|
|
96
|
+
if (input === undefined) return false
|
|
97
|
+
const prototype = Object.getPrototypeOf(input)
|
|
98
|
+
return JSON_PROTOTYPES.includes(prototype)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export const JSON_TYPE_NAMES = [
|
|
102
|
+
`array`,
|
|
103
|
+
`boolean`,
|
|
104
|
+
`null`,
|
|
105
|
+
`number`,
|
|
106
|
+
`object`,
|
|
107
|
+
`string`,
|
|
108
|
+
] as const
|
|
109
|
+
|
|
110
|
+
export type JsonTypeName = (typeof JSON_TYPE_NAMES)[number]
|
|
111
|
+
|
|
112
|
+
export interface JsonTypes extends Record<JsonTypeName, Json.Serializable> {
|
|
113
|
+
array: Json.Array
|
|
114
|
+
boolean: boolean
|
|
115
|
+
null: null
|
|
116
|
+
number: number
|
|
117
|
+
object: Json.Object
|
|
118
|
+
string: string
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export const JSON_DEFAULTS: JsonTypes = {
|
|
122
|
+
array: [],
|
|
123
|
+
boolean: false,
|
|
124
|
+
null: null,
|
|
125
|
+
number: 0,
|
|
126
|
+
object: {},
|
|
127
|
+
string: ``,
|
|
128
|
+
}
|
package/src/main/index.ts
CHANGED
|
@@ -15,7 +15,6 @@ export * from "./timeline"
|
|
|
15
15
|
export type * from "./tokens"
|
|
16
16
|
export * from "./transaction"
|
|
17
17
|
export * from "./validators"
|
|
18
|
-
|
|
19
18
|
/**
|
|
20
19
|
* Loadable is used to type atoms or selectors that may at some point be initialized to or set to a {@link Promise}.
|
|
21
20
|
*
|
|
@@ -25,4 +24,12 @@ export * from "./validators"
|
|
|
25
24
|
*/
|
|
26
25
|
export type Loadable<T> = Promise<T> | T
|
|
27
26
|
|
|
28
|
-
export type ViewOf<T> = T extends { READONLY_VIEW: infer View }
|
|
27
|
+
export type ViewOf<T> = T extends { READONLY_VIEW: infer View }
|
|
28
|
+
? View
|
|
29
|
+
: T extends Array<any>
|
|
30
|
+
? readonly [...T]
|
|
31
|
+
: T extends Set<infer U>
|
|
32
|
+
? ReadonlySet<ViewOf<U>>
|
|
33
|
+
: T extends Map<infer K, infer V>
|
|
34
|
+
? ReadonlyMap<ViewOf<K>, ViewOf<V>>
|
|
35
|
+
: T
|
package/src/main/logger.ts
CHANGED
|
@@ -82,6 +82,7 @@ export type EntityDenomination =
|
|
|
82
82
|
| `timeline`
|
|
83
83
|
| `transaction`
|
|
84
84
|
| `unknown`
|
|
85
|
+
| `user`
|
|
85
86
|
| `writable_held_selector_family`
|
|
86
87
|
| `writable_held_selector`
|
|
87
88
|
| `writable_pure_selector_family`
|
|
@@ -103,6 +104,7 @@ export const PRETTY_ENTITY_NAMES: Record<EntityDenomination, string> = {
|
|
|
103
104
|
timeline: `timeline`,
|
|
104
105
|
transaction: `transaction`,
|
|
105
106
|
unknown: `unknown`,
|
|
107
|
+
user: `👤`,
|
|
106
108
|
writable_held_selector_family: `selector family [wh]`,
|
|
107
109
|
writable_held_selector: `selector [wh]`,
|
|
108
110
|
writable_pure_selector_family: `selector family [w]`,
|
|
@@ -126,11 +128,11 @@ export type LogFilter = (
|
|
|
126
128
|
export type Logger = Record<LogLevel, LogFn>
|
|
127
129
|
|
|
128
130
|
export const simpleLog =
|
|
129
|
-
(logLevel: keyof Logger): LogFn =>
|
|
131
|
+
(logLevel: keyof Logger, prefix?: string): LogFn =>
|
|
130
132
|
(icon, denomination, tokenKey, message, ...rest) => {
|
|
131
133
|
/* eslint-disable-next-line no-console */
|
|
132
134
|
console[logLevel](
|
|
133
|
-
`${icon} ${PRETTY_ENTITY_NAMES[denomination]} \`${tokenKey}\` ${message}`,
|
|
135
|
+
`${prefix ? `${prefix} ` : ``}${icon} ${PRETTY_ENTITY_NAMES[denomination]} \`${tokenKey}\` ${message}`,
|
|
134
136
|
...rest,
|
|
135
137
|
)
|
|
136
138
|
}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
/** biome-ignore-all lint/correctness/useHookAtTopLevel: params are used in an invariant way */
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
Loadable,
|
|
4
|
+
ReadableFamilyToken,
|
|
5
|
+
ReadableToken,
|
|
6
|
+
ViewOf,
|
|
7
|
+
} from "atom.io"
|
|
3
8
|
import { findInStore, type ReadableState, withdraw } from "atom.io/internal"
|
|
4
9
|
import type { Canonical } from "atom.io/json"
|
|
5
10
|
import { StoreContext, useO } from "atom.io/react"
|
|
@@ -7,23 +12,23 @@ import { useContext, useRef } from "react"
|
|
|
7
12
|
|
|
8
13
|
export function useLoadable<T, E>(
|
|
9
14
|
token: ReadableToken<Loadable<T>, any, E>,
|
|
10
|
-
): `LOADING` | { loading: boolean; value: E | T }
|
|
15
|
+
): `LOADING` | { loading: boolean; value: ViewOf<E | T> }
|
|
11
16
|
|
|
12
17
|
export function useLoadable<T, K extends Canonical, E>(
|
|
13
18
|
token: ReadableFamilyToken<Loadable<T>, K, E>,
|
|
14
19
|
key: NoInfer<K>,
|
|
15
|
-
): `LOADING` | { loading: boolean; value: E | T }
|
|
20
|
+
): `LOADING` | { loading: boolean; value: ViewOf<E | T> }
|
|
16
21
|
|
|
17
22
|
export function useLoadable<T, F extends T, E>(
|
|
18
23
|
token: ReadableToken<Loadable<T>, any, E>,
|
|
19
24
|
fallback: F,
|
|
20
|
-
): { loading: boolean; value: T
|
|
25
|
+
): { loading: boolean; value: ViewOf<T>; error?: E }
|
|
21
26
|
|
|
22
27
|
export function useLoadable<T, K extends Canonical, F extends T, E>(
|
|
23
28
|
token: ReadableFamilyToken<Loadable<T>, K, E>,
|
|
24
29
|
key: NoInfer<K>,
|
|
25
30
|
fallback: F,
|
|
26
|
-
): { loading: boolean; value: T
|
|
31
|
+
): { loading: boolean; value: ViewOf<T>; error?: E }
|
|
27
32
|
|
|
28
33
|
export function useLoadable(
|
|
29
34
|
...params:
|
|
@@ -16,7 +16,7 @@ export const TransactionLog: FC<{
|
|
|
16
16
|
token: TransactionToken<Fn>
|
|
17
17
|
isOpenState: RegularAtomToken<boolean>
|
|
18
18
|
logState: ReadonlyPureSelectorToken<
|
|
19
|
-
TransactionOutcomeEvent<TransactionToken<Fn>>[]
|
|
19
|
+
readonly TransactionOutcomeEvent<TransactionToken<Fn>>[]
|
|
20
20
|
>
|
|
21
21
|
}> = ({ token, isOpenState, logState }) => {
|
|
22
22
|
const log = useO(logState)
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
} from "atom.io/internal"
|
|
14
14
|
import type {
|
|
15
15
|
IntrospectionStates,
|
|
16
|
-
|
|
16
|
+
ReadonlyTokenIndex,
|
|
17
17
|
} from "atom.io/introspection"
|
|
18
18
|
import { attachIntrospectionStates, isPlainObject } from "atom.io/introspection"
|
|
19
19
|
import { storageSync } from "atom.io/web"
|
|
@@ -131,8 +131,8 @@ export function attachDevtoolsStates(
|
|
|
131
131
|
do: ({ get, set }, path, current) => {
|
|
132
132
|
const currentView = get(devtoolsViewSelectionAtom)
|
|
133
133
|
let states:
|
|
134
|
-
|
|
|
135
|
-
|
|
|
134
|
+
| ReadonlyTokenIndex<AtomToken<unknown, any, any>>
|
|
135
|
+
| ReadonlyTokenIndex<SelectorToken<unknown, any, any>>
|
|
136
136
|
switch (currentView) {
|
|
137
137
|
case `atoms`:
|
|
138
138
|
states = get(introspectionStates.atomIndex)
|
|
@@ -18,10 +18,10 @@ export const useRegisterAndAttemptConfirmedUpdate =
|
|
|
18
18
|
store: RootStore,
|
|
19
19
|
continuityKey: string,
|
|
20
20
|
socket: Socket,
|
|
21
|
-
optimisticUpdates: AtomIO.TransactionOutcomeEvent<
|
|
21
|
+
optimisticUpdates: readonly AtomIO.TransactionOutcomeEvent<
|
|
22
22
|
AtomIO.TransactionToken<Fn>
|
|
23
23
|
>[],
|
|
24
|
-
confirmedUpdates: AtomIO.TransactionOutcomeEvent<
|
|
24
|
+
confirmedUpdates: readonly AtomIO.TransactionOutcomeEvent<
|
|
25
25
|
AtomIO.TransactionToken<Fn>
|
|
26
26
|
>[],
|
|
27
27
|
) =>
|
|
@@ -14,6 +14,7 @@ import type { ServerConfig } from "."
|
|
|
14
14
|
export type FamilyProvider = ReturnType<typeof realtimeAtomFamilyProvider>
|
|
15
15
|
export function realtimeAtomFamilyProvider({
|
|
16
16
|
socket,
|
|
17
|
+
userKey,
|
|
17
18
|
store = IMPLICIT.STORE,
|
|
18
19
|
}: ServerConfig) {
|
|
19
20
|
return function familyProvider<
|
|
@@ -66,6 +67,12 @@ export function realtimeAtomFamilyProvider({
|
|
|
66
67
|
familyMemberSubscriptions.set(
|
|
67
68
|
`${token.key}:unsub`,
|
|
68
69
|
employSocket(socket, `unsub:${token.key}`, () => {
|
|
70
|
+
store.logger.info(
|
|
71
|
+
`🙈`,
|
|
72
|
+
`user`,
|
|
73
|
+
userKey,
|
|
74
|
+
`unsubscribed from state "${token.key}"`,
|
|
75
|
+
)
|
|
69
76
|
fillUnsubRequest(token.key)
|
|
70
77
|
}),
|
|
71
78
|
)
|
|
@@ -81,13 +88,35 @@ export function realtimeAtomFamilyProvider({
|
|
|
81
88
|
}
|
|
82
89
|
|
|
83
90
|
const start = () => {
|
|
91
|
+
store.logger.info(
|
|
92
|
+
`👀`,
|
|
93
|
+
`user`,
|
|
94
|
+
userKey,
|
|
95
|
+
`can subscribe to family "${family.key}"`,
|
|
96
|
+
)
|
|
84
97
|
coreSubscriptions.add(
|
|
85
98
|
employSocket(socket, `sub:${family.key}`, (subKey: K) => {
|
|
86
99
|
const exposedSubKeys = getFromStore(store, index)
|
|
87
100
|
const shouldExpose = isAvailable(exposedSubKeys, subKey)
|
|
88
101
|
if (shouldExpose) {
|
|
102
|
+
store.logger.info(
|
|
103
|
+
`👀`,
|
|
104
|
+
`user`,
|
|
105
|
+
userKey,
|
|
106
|
+
`is approved for a subscription to`,
|
|
107
|
+
subKey,
|
|
108
|
+
`in family "${family.key}"`,
|
|
109
|
+
)
|
|
89
110
|
exposeFamilyMembers(subKey)
|
|
90
111
|
} else {
|
|
112
|
+
store.logger.info(
|
|
113
|
+
`❌`,
|
|
114
|
+
`user`,
|
|
115
|
+
userKey,
|
|
116
|
+
`is denied for a subscription to`,
|
|
117
|
+
subKey,
|
|
118
|
+
`in family "${family.key}"`,
|
|
119
|
+
)
|
|
91
120
|
familyMemberSubscriptionsWanted.add(stringifyJson(subKey))
|
|
92
121
|
socket.emit(`unavailable:${family.key}`, subKey)
|
|
93
122
|
}
|
|
@@ -99,8 +128,23 @@ export function realtimeAtomFamilyProvider({
|
|
|
99
128
|
index,
|
|
100
129
|
`expose-family:${family.key}:${socket.id}`,
|
|
101
130
|
({ newValue: newExposedSubKeys }) => {
|
|
131
|
+
store.logger.info(
|
|
132
|
+
`👀`,
|
|
133
|
+
`user`,
|
|
134
|
+
userKey,
|
|
135
|
+
`has the following keys available for family "${family.key}"`,
|
|
136
|
+
newExposedSubKeys,
|
|
137
|
+
)
|
|
102
138
|
for (const subKey of newExposedSubKeys) {
|
|
103
139
|
if (familyMemberSubscriptionsWanted.has(stringifyJson(subKey))) {
|
|
140
|
+
store.logger.info(
|
|
141
|
+
`👀`,
|
|
142
|
+
`user`,
|
|
143
|
+
userKey,
|
|
144
|
+
`is retroactively approved for a subscription to`,
|
|
145
|
+
subKey,
|
|
146
|
+
`in family "${family.key}"`,
|
|
147
|
+
)
|
|
104
148
|
exposeFamilyMembers(subKey)
|
|
105
149
|
}
|
|
106
150
|
}
|
|
@@ -31,6 +31,7 @@ export type MutableFamilyProvider = ReturnType<
|
|
|
31
31
|
>
|
|
32
32
|
export function realtimeMutableFamilyProvider({
|
|
33
33
|
socket,
|
|
34
|
+
userKey,
|
|
34
35
|
store = IMPLICIT.STORE,
|
|
35
36
|
}: ServerConfig) {
|
|
36
37
|
return function mutableFamilyProvider<
|
|
@@ -91,13 +92,35 @@ export function realtimeMutableFamilyProvider({
|
|
|
91
92
|
}
|
|
92
93
|
|
|
93
94
|
const start = () => {
|
|
95
|
+
store.logger.info(
|
|
96
|
+
`👀`,
|
|
97
|
+
`user`,
|
|
98
|
+
userKey,
|
|
99
|
+
`can subscribe to family "${family.key}"`,
|
|
100
|
+
)
|
|
94
101
|
coreSubscriptions.add(
|
|
95
102
|
employSocket(socket, `sub:${family.key}`, (subKey: K) => {
|
|
96
103
|
const exposedSubKeys = getFromStore(store, index)
|
|
97
104
|
const shouldExpose = isAvailable(exposedSubKeys, subKey)
|
|
98
105
|
if (shouldExpose) {
|
|
106
|
+
store.logger.info(
|
|
107
|
+
`👀`,
|
|
108
|
+
`user`,
|
|
109
|
+
userKey,
|
|
110
|
+
`is approved for a subscription to`,
|
|
111
|
+
subKey,
|
|
112
|
+
`in family "${family.key}"`,
|
|
113
|
+
)
|
|
99
114
|
exposeFamilyMembers(subKey)
|
|
100
115
|
} else {
|
|
116
|
+
store.logger.info(
|
|
117
|
+
`❌`,
|
|
118
|
+
`user`,
|
|
119
|
+
userKey,
|
|
120
|
+
`is denied for a subscription to`,
|
|
121
|
+
subKey,
|
|
122
|
+
`in family "${family.key}"`,
|
|
123
|
+
)
|
|
101
124
|
familyMemberSubscriptionsWanted.add(stringifyJson(subKey))
|
|
102
125
|
socket.emit(`unavailable:${family.key}`, subKey)
|
|
103
126
|
}
|
|
@@ -109,8 +132,23 @@ export function realtimeMutableFamilyProvider({
|
|
|
109
132
|
index,
|
|
110
133
|
`expose-family:${family.key}:${socket.id}`,
|
|
111
134
|
({ newValue: newExposedSubKeys }) => {
|
|
135
|
+
store.logger.info(
|
|
136
|
+
`👀`,
|
|
137
|
+
`user`,
|
|
138
|
+
userKey,
|
|
139
|
+
`has the following keys available for family "${family.key}"`,
|
|
140
|
+
newExposedSubKeys,
|
|
141
|
+
)
|
|
112
142
|
for (const subKey of newExposedSubKeys) {
|
|
113
143
|
if (familyMemberSubscriptionsWanted.has(stringifyJson(subKey))) {
|
|
144
|
+
store.logger.info(
|
|
145
|
+
`👀`,
|
|
146
|
+
`user`,
|
|
147
|
+
userKey,
|
|
148
|
+
`is retroactively approved for a subscription to`,
|
|
149
|
+
subKey,
|
|
150
|
+
`in family "${family.key}"`,
|
|
151
|
+
)
|
|
114
152
|
exposeFamilyMembers(subKey)
|
|
115
153
|
}
|
|
116
154
|
}
|
|
@@ -15,6 +15,7 @@ import type { ServerConfig } from "."
|
|
|
15
15
|
export type MutableProvider = ReturnType<typeof realtimeMutableProvider>
|
|
16
16
|
export function realtimeMutableProvider({
|
|
17
17
|
socket,
|
|
18
|
+
userKey,
|
|
18
19
|
store = IMPLICIT.STORE,
|
|
19
20
|
}: ServerConfig) {
|
|
20
21
|
return function mutableProvider<
|
|
@@ -30,8 +31,20 @@ export function realtimeMutableProvider({
|
|
|
30
31
|
const trackerToken = getUpdateToken(token)
|
|
31
32
|
|
|
32
33
|
const start = () => {
|
|
34
|
+
store.logger.info(
|
|
35
|
+
`👀`,
|
|
36
|
+
`user`,
|
|
37
|
+
userKey,
|
|
38
|
+
`can subscribe to state "${token.key}"`,
|
|
39
|
+
)
|
|
33
40
|
subscriptions.add(
|
|
34
41
|
employSocket(socket, `sub:${token.key}`, () => {
|
|
42
|
+
store.logger.info(
|
|
43
|
+
`👀`,
|
|
44
|
+
`user`,
|
|
45
|
+
userKey,
|
|
46
|
+
`subscribes to state "${token.key}"`,
|
|
47
|
+
)
|
|
35
48
|
clearSubscriptions()
|
|
36
49
|
socket.emit(`init:${token.key}`, getFromStore(store, jsonToken))
|
|
37
50
|
subscriptions.add(
|
|
@@ -46,6 +59,12 @@ export function realtimeMutableProvider({
|
|
|
46
59
|
)
|
|
47
60
|
subscriptions.add(
|
|
48
61
|
employSocket(socket, `unsub:${token.key}`, () => {
|
|
62
|
+
store.logger.info(
|
|
63
|
+
`🙈`,
|
|
64
|
+
`user`,
|
|
65
|
+
userKey,
|
|
66
|
+
`unsubscribes from state "${token.key}"`,
|
|
67
|
+
)
|
|
49
68
|
clearSubscriptions()
|
|
50
69
|
start()
|
|
51
70
|
}),
|
|
@@ -252,10 +252,11 @@ export function provideRooms<RoomNames extends string>({
|
|
|
252
252
|
createRoomSocketGuard(roomNames),
|
|
253
253
|
)
|
|
254
254
|
|
|
255
|
-
const exposeMutable = realtimeMutableProvider({ socket, store })
|
|
255
|
+
const exposeMutable = realtimeMutableProvider({ socket, store, userKey })
|
|
256
256
|
const exposeMutableFamily = realtimeMutableFamilyProvider({
|
|
257
257
|
socket,
|
|
258
258
|
store,
|
|
259
|
+
userKey,
|
|
259
260
|
})
|
|
260
261
|
|
|
261
262
|
exposeMutable(roomKeysAtom)
|
|
@@ -8,8 +8,10 @@ import type { ServerConfig } from "."
|
|
|
8
8
|
export type StateProvider = ReturnType<typeof realtimeStateProvider>
|
|
9
9
|
export function realtimeStateProvider({
|
|
10
10
|
socket,
|
|
11
|
+
userKey,
|
|
11
12
|
store = IMPLICIT.STORE,
|
|
12
13
|
}: ServerConfig) {
|
|
14
|
+
store.logger.info(`🔌`, `user`, userKey, `initialized state provider`)
|
|
13
15
|
return function stateProvider<J extends Json.Serializable>(
|
|
14
16
|
token: AtomIO.WritableToken<J>,
|
|
15
17
|
): () => void {
|
|
@@ -20,8 +22,20 @@ export function realtimeStateProvider({
|
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
const start = () => {
|
|
25
|
+
store.logger.info(
|
|
26
|
+
`👀`,
|
|
27
|
+
`user`,
|
|
28
|
+
userKey,
|
|
29
|
+
`can subscribe to state "${token.key}"`,
|
|
30
|
+
)
|
|
23
31
|
subscriptions.add(
|
|
24
32
|
employSocket(socket, `sub:${token.key}`, () => {
|
|
33
|
+
store.logger.info(
|
|
34
|
+
`👀`,
|
|
35
|
+
`user`,
|
|
36
|
+
userKey,
|
|
37
|
+
`subscribes to state "${token.key}"`,
|
|
38
|
+
)
|
|
25
39
|
clearSubscriptions()
|
|
26
40
|
socket.emit(`serve:${token.key}`, getFromStore(store, token))
|
|
27
41
|
subscriptions.add(
|
|
@@ -36,6 +50,12 @@ export function realtimeStateProvider({
|
|
|
36
50
|
)
|
|
37
51
|
subscriptions.add(
|
|
38
52
|
employSocket(socket, `unsub:${token.key}`, () => {
|
|
53
|
+
store.logger.info(
|
|
54
|
+
`🙈`,
|
|
55
|
+
`user`,
|
|
56
|
+
userKey,
|
|
57
|
+
`unsubscribes from state "${token.key}"`,
|
|
58
|
+
)
|
|
39
59
|
clearSubscriptions()
|
|
40
60
|
start()
|
|
41
61
|
}),
|
|
@@ -54,15 +54,9 @@ function prefixLogger(store: Store, prefix: string) {
|
|
|
54
54
|
return params
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
|
-
info: (
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
warn: (...params) => {
|
|
61
|
-
console.warn(prefix, ...params)
|
|
62
|
-
},
|
|
63
|
-
error: (...params) => {
|
|
64
|
-
console.error(prefix, ...params)
|
|
65
|
-
},
|
|
57
|
+
info: AtomIO.simpleLog(`info`, prefix),
|
|
58
|
+
warn: AtomIO.simpleLog(`warn`, prefix),
|
|
59
|
+
error: AtomIO.simpleLog(`error`, prefix),
|
|
66
60
|
},
|
|
67
61
|
)
|
|
68
62
|
}
|