atom.io 0.18.0 → 0.18.1

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.
Files changed (83) hide show
  1. package/dist/{chunk-OEVFAUPE.js → chunk-IZHOMSXA.js} +53 -11
  2. package/dist/chunk-IZHOMSXA.js.map +1 -0
  3. package/dist/chunk-JDUNWJFB.js +18 -0
  4. package/dist/chunk-JDUNWJFB.js.map +1 -0
  5. package/dist/index.cjs.map +1 -1
  6. package/dist/index.d.ts +5 -1
  7. package/dist/index.js.map +1 -1
  8. package/internal/dist/index.cjs +64 -34
  9. package/internal/dist/index.cjs.map +1 -1
  10. package/internal/dist/index.d.ts +1 -1
  11. package/internal/dist/index.js +64 -34
  12. package/internal/dist/index.js.map +1 -1
  13. package/internal/src/atom/delete-atom.ts +7 -6
  14. package/internal/src/caching.ts +6 -6
  15. package/internal/src/ingest-updates/ingest-atom-update.ts +6 -2
  16. package/internal/src/set-state/copy-mutable-if-needed.ts +5 -0
  17. package/internal/src/set-state/emit-update.ts +25 -11
  18. package/internal/src/set-state/set-atom.ts +4 -3
  19. package/internal/src/transaction/apply-transaction.ts +0 -1
  20. package/internal/src/transaction/set-epoch-number.ts +0 -1
  21. package/json/src/index.ts +3 -3
  22. package/package.json +241 -241
  23. package/react-devtools/dist/index.cjs.map +1 -1
  24. package/react-devtools/dist/index.js +1 -15
  25. package/react-devtools/dist/index.js.map +1 -1
  26. package/react-devtools/src/StateEditor.tsx +6 -6
  27. package/react-devtools/src/StateIndex.tsx +2 -2
  28. package/react-devtools/src/Updates.tsx +1 -1
  29. package/react-devtools/src/index.ts +3 -3
  30. package/realtime/dist/index.cjs +50 -2
  31. package/realtime/dist/index.cjs.map +1 -1
  32. package/realtime/dist/index.d.ts +110 -3
  33. package/realtime/dist/index.js +47 -4
  34. package/realtime/dist/index.js.map +1 -1
  35. package/realtime/src/index.ts +1 -0
  36. package/realtime/src/realtime-continuity.ts +14 -4
  37. package/realtime/src/shared-room-store.ts +48 -0
  38. package/realtime-client/dist/index.cjs +113 -200
  39. package/realtime-client/dist/index.cjs.map +1 -1
  40. package/realtime-client/dist/index.d.ts +2 -5
  41. package/realtime-client/dist/index.js +17 -161
  42. package/realtime-client/dist/index.js.map +1 -1
  43. package/realtime-client/src/index.ts +0 -2
  44. package/realtime-client/src/pull-mutable-atom-family-member.ts +5 -5
  45. package/realtime-client/src/realtime-client-stores/client-main-store.ts +10 -0
  46. package/realtime-client/src/sync-continuity.ts +56 -9
  47. package/realtime-react/dist/index.cjs +51 -26
  48. package/realtime-react/dist/index.cjs.map +1 -1
  49. package/realtime-react/dist/index.d.ts +2 -6
  50. package/realtime-react/dist/index.js +2 -17
  51. package/realtime-react/dist/index.js.map +1 -1
  52. package/realtime-react/src/index.ts +0 -2
  53. package/realtime-server/dist/index.cjs +399 -327
  54. package/realtime-server/dist/index.cjs.map +1 -1
  55. package/realtime-server/dist/index.d.ts +55 -60
  56. package/realtime-server/dist/index.js +394 -319
  57. package/realtime-server/dist/index.js.map +1 -1
  58. package/realtime-server/src/index.ts +2 -4
  59. package/realtime-server/src/ipc-sockets/child-socket.ts +135 -0
  60. package/realtime-server/src/ipc-sockets/custom-socket.ts +90 -0
  61. package/realtime-server/src/ipc-sockets/index.ts +3 -0
  62. package/realtime-server/src/ipc-sockets/parent-socket.ts +185 -0
  63. package/realtime-server/src/realtime-continuity-synchronizer.ts +225 -96
  64. package/realtime-server/src/realtime-server-stores/index.ts +2 -1
  65. package/realtime-server/src/realtime-server-stores/realtime-continuity-store.ts +50 -31
  66. package/realtime-server/src/realtime-server-stores/server-room-external-actions.ts +64 -0
  67. package/realtime-server/src/realtime-server-stores/server-room-external-store.ts +42 -0
  68. package/realtime-server/src/realtime-server-stores/server-sync-store.ts +49 -26
  69. package/realtime-testing/dist/index.cjs +8 -6
  70. package/realtime-testing/dist/index.cjs.map +1 -1
  71. package/realtime-testing/dist/index.d.ts +1 -0
  72. package/realtime-testing/dist/index.js +7 -6
  73. package/realtime-testing/dist/index.js.map +1 -1
  74. package/realtime-testing/src/setup-realtime-test.tsx +8 -6
  75. package/src/logger.ts +5 -1
  76. package/dist/chunk-OEVFAUPE.js.map +0 -1
  77. package/realtime-client/src/sync-server-action.ts +0 -168
  78. package/realtime-client/src/sync-state.ts +0 -19
  79. package/realtime-react/src/use-sync-server-action.ts +0 -17
  80. package/realtime-react/src/use-sync.ts +0 -17
  81. package/realtime-server/src/ipc-socket.ts +0 -230
  82. package/realtime-server/src/realtime-action-synchronizer.ts +0 -164
  83. package/realtime-server/src/realtime-server-stores/server-room-store.ts +0 -97
@@ -2,12 +2,12 @@ import type { ReadonlySelectorToken, WritableToken } from "atom.io"
2
2
  import { useI, useO } from "atom.io/react"
3
3
  import type { FC } from "react"
4
4
 
5
- import { fallback } from "anvl/function"
6
- import { Join } from "anvl/join"
7
- import { isJson } from "anvl/refinement"
8
- import { RelationEditor } from "hamr/react-data-designer"
9
- import { ElasticInput } from "hamr/react-elastic-input"
10
- import { JsonEditor } from "hamr/react-json-editor"
5
+ import { fallback } from "~/packages/anvl/src/function"
6
+ import { Join } from "~/packages/anvl/src/join"
7
+ import { isJson } from "~/packages/anvl/src/refinement"
8
+ import { RelationEditor } from "~/packages/hamr/react-data-designer/src"
9
+ import { ElasticInput } from "~/packages/hamr/react-elastic-input/src"
10
+ import { JsonEditor } from "~/packages/hamr/react-json-editor/src"
11
11
 
12
12
  export const StateEditor: FC<{
13
13
  token: WritableToken<unknown>
@@ -8,8 +8,8 @@ import type { FamilyNode, WritableTokenIndex } from "atom.io/introspection"
8
8
  import { useI, useO } from "atom.io/react"
9
9
  import type { FC } from "react"
10
10
 
11
- import { recordToEntries } from "anvl/object"
12
- import { isJson, refineJsonType } from "anvl/refinement"
11
+ import { recordToEntries } from "~/packages/anvl/src/object"
12
+ import { isJson, refineJsonType } from "~/packages/anvl/src/refinement"
13
13
 
14
14
  import { findViewIsOpenState, primitiveRefinery } from "."
15
15
  import { button } from "./Button"
@@ -6,7 +6,7 @@ import type {
6
6
  } from "atom.io"
7
7
  import * as React from "react"
8
8
 
9
- import { discoverType } from "anvl/refinement/refinery"
9
+ import { discoverType } from "~/packages/anvl/src/refinement/refinery"
10
10
 
11
11
  import { prettyJson } from "."
12
12
 
@@ -1,8 +1,8 @@
1
1
  import { atom, atomFamily } from "atom.io"
2
2
  import { attachIntrospectionStates } from "atom.io/introspection"
3
3
 
4
- import { isPlainObject } from "anvl/object"
5
- import { Refinery } from "anvl/refinement"
4
+ import { isPlainObject } from "~/packages/anvl/src/object"
5
+ import { Refinery } from "~/packages/anvl/src/refinement"
6
6
  import {
7
7
  Differ,
8
8
  diffArray,
@@ -10,7 +10,7 @@ import {
10
10
  diffNumber,
11
11
  diffObject,
12
12
  diffString,
13
- } from "anvl/tree/differ"
13
+ } from "~/packages/anvl/src/tree/differ"
14
14
  import { lazyLocalStorageEffect } from "~/packages/atom.io/__unstable__/web-effects/src"
15
15
 
16
16
  export * from "./AtomIODevtools"
@@ -1,6 +1,9 @@
1
1
  'use strict';
2
2
 
3
3
  var internal = require('atom.io/internal');
4
+ var atom_io = require('atom.io');
5
+ var data = require('atom.io/data');
6
+ var setRtx = require('atom.io/transceivers/set-rtx');
4
7
 
5
8
  // realtime/src/realtime-continuity.ts
6
9
  var InvariantMap = class extends Map {
@@ -37,7 +40,16 @@ var _SyncGroup = class _SyncGroup {
37
40
  const zeroth = args[0];
38
41
  if (zeroth.type === `atom` || zeroth.type === `mutable_atom`) {
39
42
  const globals = args;
40
- this.globals.push(...globals);
43
+ for (const global of globals) {
44
+ switch (global.type) {
45
+ case `atom`:
46
+ this.globals.push(global);
47
+ break;
48
+ case `mutable_atom`:
49
+ this.globals.push(internal.getUpdateToken(global));
50
+ break;
51
+ }
52
+ }
41
53
  } else if (zeroth.type === `transaction`) {
42
54
  const actions = args;
43
55
  this.actions.push(...actions);
@@ -46,7 +58,7 @@ var _SyncGroup = class _SyncGroup {
46
58
  this.perspectives.push({
47
59
  type: `realtime_perspective`,
48
60
  resourceAtoms: family,
49
- perspectiveAtoms: index
61
+ viewAtoms: index
50
62
  });
51
63
  }
52
64
  return this;
@@ -64,9 +76,45 @@ function continuity(options) {
64
76
  internal.setEpochNumberOfContinuity(key, -1, internal.IMPLICIT.STORE);
65
77
  return token;
66
78
  }
79
+ var usersInThisRoomIndex = atom_io.atom({
80
+ key: `usersInRoomIndex`,
81
+ mutable: true,
82
+ default: () => new setRtx.SetRTX(),
83
+ toJson: (set) => set.toJSON(),
84
+ fromJson: (json) => setRtx.SetRTX.fromJSON(json)
85
+ });
86
+ var roomIndex = atom_io.atom({
87
+ key: `roomIndex`,
88
+ default: () => new setRtx.SetRTX(),
89
+ mutable: true,
90
+ toJson: (set) => set.toJSON(),
91
+ fromJson: (json) => setRtx.SetRTX.fromJSON(json)
92
+ });
93
+ var DEFAULT_USER_IN_ROOM_META = {
94
+ enteredAtEpoch: 0
95
+ };
96
+ var usersInRooms = data.join(
97
+ {
98
+ key: `usersInRooms`,
99
+ between: [`room`, `user`],
100
+ cardinality: `1:n`
101
+ },
102
+ DEFAULT_USER_IN_ROOM_META
103
+ );
104
+ var usersInMyRoomView = atom_io.selectorFamily({
105
+ key: `usersInMyRoomView`,
106
+ get: (username) => ({ find }) => {
107
+ return [find(usersInRooms.core.findRelatedKeysState, username)];
108
+ }
109
+ });
67
110
 
111
+ exports.DEFAULT_USER_IN_ROOM_META = DEFAULT_USER_IN_ROOM_META;
68
112
  exports.InvariantMap = InvariantMap;
69
113
  exports.SyncGroup = SyncGroup;
70
114
  exports.continuity = continuity;
115
+ exports.roomIndex = roomIndex;
116
+ exports.usersInMyRoomView = usersInMyRoomView;
117
+ exports.usersInRooms = usersInRooms;
118
+ exports.usersInThisRoomIndex = usersInThisRoomIndex;
71
119
  //# sourceMappingURL=out.js.map
72
120
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/realtime-continuity.ts"],"names":[],"mappings":";AAOA;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,OACM;AAGA,IAAM,eAAN,cAAiC,IAAU;AAAA,EAC1C,IAAI,KAAQ,OAAgB;AAClC,QAAI,KAAK,IAAI,GAAG,GAAG;AAClB,cAAQ,KAAK,6DAA6D;AAAA,QACzE;AAAA,QACA;AAAA,MACD,CAAC;AACD,aAAO;AAAA,IACR;AACA,WAAO,MAAM,IAAI,KAAK,KAAK;AAAA,EAC5B;AAAA,EAEO,QAAc;AACpB,UAAM,IAAI,MAAM,8BAA8B;AAAA,EAC/C;AACD;AAsBO,IAAM,aAAN,MAAM,WAAU;AAAA,EAOZ,YAA+B,KAAa;AAAb;AANzC,SAAU,OAAO;AAEjB,SAAU,UAA4B,CAAC;AACvC,SAAU,UAAmC,CAAC;AAC9C,SAAU,eAA6C,CAAC;AAAA,EAED;AAAA,EAIvD,OAAc,OACb,KACA,SACkB;AAClB,UAAM,QAAQ,IAAI,WAAU,GAAG;AAC/B,UAAM,EAAE,MAAM,SAAS,SAAS,aAAa,IAAI,QAAQ,KAAK;AAC9D,UAAM,QAAQ,EAAE,MAAM,KAAK,SAAS,SAAS,aAAa;AAC1D,eAAU,SAAS,IAAI,KAAK,KAAK;AACjC,WAAO;AAAA,EACR;AAAA,EAWO,OACH,MAIS;AACZ,UAAM,SAAS,KAAK,CAAC;AACrB,QAAI,OAAO,SAAS,UAAU,OAAO,SAAS,gBAAgB;AAC7D,YAAM,UAAU;AAChB,WAAK,QAAQ,KAAK,GAAG,OAAO;AAAA,IAC7B,WAAW,OAAO,SAAS,eAAe;AACzC,YAAM,UAAU;AAChB,WAAK,QAAQ,KAAK,GAAG,OAAO;AAAA,IAC7B,OAAO;AACN,YAAM,CAAC,QAAQ,KAAK,IAAI;AAIxB,WAAK,aAAa,KAAK;AAAA,QACtB,MAAM;AAAA,QACN,eAAe;AAAA,QACf,kBAAkB;AAAA,MACnB,CAAC;AAAA,IACF;AACA,WAAO;AAAA,EACR;AACD;AAzDa,WASE,WACb,IAAI,aAAa;AAVZ,IAAM,YAAN;AAgEA,SAAS,WAAW,SAA6C;AACvE,QAAM,EAAE,KAAK,OAAO,IAAI;AACxB,QAAM,QAAQ,UAAU,OAAO,KAAK,MAAM;AAC1C,QAAM,EAAE,QAAQ,IAAI;AACpB,aAAW,UAAU,SAAS;AAC7B,kCAA8B,KAAK,OAAO,KAAK,SAAS,KAAK;AAAA,EAC9D;AACA,6BAA2B,KAAK,IAAI,SAAS,KAAK;AAClD,SAAO;AACR","sourcesContent":["import type {\n\tAtomFamilyToken,\n\tAtomToken,\n\tReadableFamilyToken,\n\tReadableToken,\n\tTransactionToken,\n} from \"atom.io\"\nimport {\n\tIMPLICIT,\n\tassignTransactionToContinuity,\n\tsetEpochNumberOfContinuity,\n} from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\n\nexport class InvariantMap<K, V> extends Map<K, V> {\n\tpublic set(key: K, value: V): this {\n\t\tif (this.has(key)) {\n\t\t\tconsole.warn(`Tried to set a key that already exists in an InvariantMap`, {\n\t\t\t\tkey,\n\t\t\t\tvalue,\n\t\t\t})\n\t\t\treturn this\n\t\t}\n\t\treturn super.set(key, value)\n\t}\n\n\tpublic clear(): void {\n\t\tthrow new Error(`Cannot clear an InvariantMap`)\n\t}\n}\n\nexport type PerspectiveToken<\n\tF extends AtomFamilyToken<any>,\n\tT extends F extends AtomFamilyToken<infer T, any> ? T : never,\n> = {\n\ttype: `realtime_perspective`\n\tresourceAtoms: F\n\tperspectiveAtoms: ReadableFamilyToken<Iterable<ReadableToken<T>>, string>\n}\n\nexport type ContinuityToken = {\n\treadonly type: `continuity`\n\treadonly key: string\n\treadonly globals: AtomToken<any>[]\n\treadonly actions: TransactionToken<any>[]\n\treadonly perspectives: PerspectiveToken<\n\t\tAtomFamilyToken<any, Json.Serializable>,\n\t\tJson.Serializable\n\t>[]\n}\n\nexport class SyncGroup {\n\tprotected type = `continuity` as const\n\n\tprotected globals: AtomToken<any>[] = []\n\tprotected actions: TransactionToken<any>[] = []\n\tprotected perspectives: PerspectiveToken<any, any>[] = []\n\n\tprotected constructor(protected readonly key: string) {}\n\n\tpublic static existing: InvariantMap<string, ContinuityToken> =\n\t\tnew InvariantMap()\n\tpublic static create(\n\t\tkey: string,\n\t\tbuilder: (group: SyncGroup) => SyncGroup,\n\t): ContinuityToken {\n\t\tconst group = new SyncGroup(key)\n\t\tconst { type, globals, actions, perspectives } = builder(group)\n\t\tconst token = { type, key, globals, actions, perspectives }\n\t\tSyncGroup.existing.set(key, token)\n\t\treturn token\n\t}\n\n\tpublic add(...atoms: AtomToken<any>[]): SyncGroup\n\tpublic add(...args: TransactionToken<any>[]): SyncGroup\n\tpublic add<\n\t\tF extends AtomFamilyToken<any>,\n\t\tT extends F extends AtomFamilyToken<infer T> ? T : never,\n\t>(\n\t\tfamily: AtomFamilyToken<T, any>,\n\t\tindex: ReadableFamilyToken<Iterable<AtomToken<T>>, string>,\n\t): SyncGroup\n\tpublic add(\n\t\t...args:\n\t\t\t| readonly AtomToken<any>[]\n\t\t\t| readonly TransactionToken<any>[]\n\t\t\t| [AtomFamilyToken<any, any>, ReadableFamilyToken<Iterable<any>, string>]\n\t): SyncGroup {\n\t\tconst zeroth = args[0]\n\t\tif (zeroth.type === `atom` || zeroth.type === `mutable_atom`) {\n\t\t\tconst globals = args as AtomToken<any>[]\n\t\t\tthis.globals.push(...globals)\n\t\t} else if (zeroth.type === `transaction`) {\n\t\t\tconst actions = args as TransactionToken<any>[]\n\t\t\tthis.actions.push(...actions)\n\t\t} else {\n\t\t\tconst [family, index] = args as [\n\t\t\t\tAtomFamilyToken<any, any>,\n\t\t\t\tReadableFamilyToken<Iterable<any>, string>,\n\t\t\t]\n\t\t\tthis.perspectives.push({\n\t\t\t\ttype: `realtime_perspective`,\n\t\t\t\tresourceAtoms: family,\n\t\t\t\tperspectiveAtoms: index,\n\t\t\t})\n\t\t}\n\t\treturn this\n\t}\n}\n\nexport type ContinuityOptions = {\n\tkey: string\n\tconfig: (group: SyncGroup) => SyncGroup\n}\n\nexport function continuity(options: ContinuityOptions): ContinuityToken {\n\tconst { key, config } = options\n\tconst token = SyncGroup.create(key, config)\n\tconst { actions } = token\n\tfor (const action of actions) {\n\t\tassignTransactionToContinuity(key, action.key, IMPLICIT.STORE)\n\t}\n\tsetEpochNumberOfContinuity(key, -1, IMPLICIT.STORE)\n\treturn token\n}\n\n// const counterStates = atomFamily<number, { c: string }>({\n// \tkey: `counter`,\n// \tdefault: 0,\n// })\n// const counterIndices = atomFamily<{ c: string }[], string>({\n// \tkey: `counterIndex`,\n// \tdefault: [],\n// })\n// const nameStates = atomFamily<number, { n: string }>({\n// \tkey: `name`,\n// \tdefault: 0,\n// })\n// const nameIndices = atomFamily<{ n: string }[], string>({\n// \tkey: `nameIndex`,\n// \tdefault: [],\n// })\n\n// const counterContinuity = continuity({\n// \tkey: `counter`,\n// \tconfig: (group) =>\n// \t\tgroup\n// \t\t\t.add(counterStates, counterIndices)\n// \t\t\t.add(nameStates, nameIndices)\n// \t\t\t.add(nameStates, nameIndices)\n// \t\t\t.add(nameStates, nameIndices),\n// })\n"]}
1
+ {"version":3,"sources":["../src/realtime-continuity.ts","../src/shared-room-store.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tAtomFamilyToken,\n\tAtomToken,\n\tReadableFamilyToken,\n\tReadableToken,\n\tTransactionToken,\n} from \"atom.io\"\nimport {\n\tIMPLICIT,\n\tassignTransactionToContinuity,\n\tgetUpdateToken,\n\tsetEpochNumberOfContinuity,\n} from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\n\nexport class InvariantMap<K, V> extends Map<K, V> {\n\tpublic set(key: K, value: V): this {\n\t\tif (this.has(key)) {\n\t\t\tconsole.warn(`Tried to set a key that already exists in an InvariantMap`, {\n\t\t\t\tkey,\n\t\t\t\tvalue,\n\t\t\t})\n\t\t\treturn this\n\t\t}\n\t\treturn super.set(key, value)\n\t}\n\n\tpublic clear(): void {\n\t\tthrow new Error(`Cannot clear an InvariantMap`)\n\t}\n}\n\nexport type PerspectiveToken<\n\tF extends AtomFamilyToken<any>,\n\tT extends F extends AtomFamilyToken<infer T, any> ? T : never,\n> = {\n\ttype: `realtime_perspective`\n\tresourceAtoms: F\n\tviewAtoms: ReadableFamilyToken<ReadableToken<T>[], string>\n}\n\nexport type ContinuityToken = {\n\treadonly type: `continuity`\n\treadonly key: string\n\treadonly globals: AtomToken<any>[]\n\treadonly actions: TransactionToken<any>[]\n\treadonly perspectives: PerspectiveToken<\n\t\tAtomFamilyToken<any, Json.Serializable>,\n\t\tJson.Serializable\n\t>[]\n}\n\nexport class SyncGroup {\n\tprotected type = `continuity` as const\n\n\tprotected globals: AtomToken<any>[] = []\n\tprotected actions: TransactionToken<any>[] = []\n\tprotected perspectives: PerspectiveToken<any, any>[] = []\n\n\tprotected constructor(protected readonly key: string) {}\n\n\tpublic static existing: InvariantMap<string, ContinuityToken> =\n\t\tnew InvariantMap()\n\tpublic static create(\n\t\tkey: string,\n\t\tbuilder: (group: SyncGroup) => SyncGroup,\n\t): ContinuityToken {\n\t\tconst group = new SyncGroup(key)\n\t\tconst { type, globals, actions, perspectives } = builder(group)\n\t\tconst token = { type, key, globals, actions, perspectives }\n\t\tSyncGroup.existing.set(key, token)\n\t\treturn token\n\t}\n\n\tpublic add(...atoms: AtomToken<any>[]): SyncGroup\n\tpublic add(...args: TransactionToken<any>[]): SyncGroup\n\tpublic add<\n\t\tF extends AtomFamilyToken<any>,\n\t\tT extends F extends AtomFamilyToken<infer T> ? T : never,\n\t>(\n\t\tfamily: AtomFamilyToken<T, any>,\n\t\tindex: ReadableFamilyToken<Iterable<AtomToken<T>>, string>,\n\t): SyncGroup\n\tpublic add(\n\t\t...args:\n\t\t\t| readonly AtomToken<any>[]\n\t\t\t| readonly TransactionToken<any>[]\n\t\t\t| [AtomFamilyToken<any, any>, ReadableFamilyToken<Iterable<any>, string>]\n\t): SyncGroup {\n\t\tconst zeroth = args[0]\n\t\tif (zeroth.type === `atom` || zeroth.type === `mutable_atom`) {\n\t\t\tconst globals = args as AtomToken<any>[]\n\t\t\tfor (const global of globals) {\n\t\t\t\tswitch (global.type) {\n\t\t\t\t\tcase `atom`:\n\t\t\t\t\t\tthis.globals.push(global)\n\t\t\t\t\t\tbreak\n\t\t\t\t\tcase `mutable_atom`:\n\t\t\t\t\t\tthis.globals.push(getUpdateToken(global))\n\t\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (zeroth.type === `transaction`) {\n\t\t\tconst actions = args as TransactionToken<any>[]\n\t\t\tthis.actions.push(...actions)\n\t\t} else {\n\t\t\tconst [family, index] = args as [\n\t\t\t\tAtomFamilyToken<any, any>,\n\t\t\t\tReadableFamilyToken<ReadableToken<any>[], string>,\n\t\t\t]\n\t\t\tthis.perspectives.push({\n\t\t\t\ttype: `realtime_perspective`,\n\t\t\t\tresourceAtoms: family,\n\t\t\t\tviewAtoms: index,\n\t\t\t})\n\t\t}\n\t\treturn this\n\t}\n}\n\nexport type ContinuityOptions = {\n\tkey: string\n\tconfig: (group: SyncGroup) => SyncGroup\n}\n\nexport function continuity(options: ContinuityOptions): ContinuityToken {\n\tconst { key, config } = options\n\tconst token = SyncGroup.create(key, config)\n\tconst { actions } = token\n\tfor (const action of actions) {\n\t\tassignTransactionToContinuity(key, action.key, IMPLICIT.STORE)\n\t}\n\tsetEpochNumberOfContinuity(key, -1, IMPLICIT.STORE)\n\treturn token\n}\n\n// const counterStates = atomFamily<number, { c: string }>({\n// \tkey: `counter`,\n// \tdefault: 0,\n// })\n// const counterIndices = atomFamily<{ c: string }[], string>({\n// \tkey: `counterIndex`,\n// \tdefault: [],\n// })\n// const nameStates = atomFamily<number, { n: string }>({\n// \tkey: `name`,\n// \tdefault: 0,\n// })\n// const nameIndices = atomFamily<{ n: string }[], string>({\n// \tkey: `nameIndex`,\n// \tdefault: [],\n// })\n\n// const counterContinuity = continuity({\n// \tkey: `counter`,\n// \tconfig: (group) =>\n// \t\tgroup\n// \t\t\t.add(counterStates, counterIndices)\n// \t\t\t.add(nameStates, nameIndices)\n// \t\t\t.add(nameStates, nameIndices)\n// \t\t\t.add(nameStates, nameIndices),\n// })\n","import type { MutableAtomToken } from \"atom.io\"\nimport { atom, selectorFamily } from \"atom.io\"\nimport { join } from \"atom.io/data\"\nimport type { SetRTXJson } from \"atom.io/transceivers/set-rtx\"\nimport { SetRTX } from \"atom.io/transceivers/set-rtx\"\n\nexport const usersInThisRoomIndex = atom<SetRTX<string>, SetRTXJson<string>>({\n\tkey: `usersInRoomIndex`,\n\tmutable: true,\n\tdefault: () => new SetRTX<string>(),\n\ttoJson: (set) => set.toJSON(),\n\tfromJson: (json) => SetRTX.fromJSON(json),\n})\n\nexport const roomIndex = atom({\n\tkey: `roomIndex`,\n\tdefault: () => new SetRTX<string>(),\n\tmutable: true,\n\ttoJson: (set) => set.toJSON(),\n\tfromJson: (json) => SetRTX.fromJSON(json),\n})\n\nexport type UserInRoomMeta = {\n\tenteredAtEpoch: number\n}\nexport const DEFAULT_USER_IN_ROOM_META: UserInRoomMeta = {\n\tenteredAtEpoch: 0,\n}\nexport const usersInRooms = join(\n\t{\n\t\tkey: `usersInRooms`,\n\t\tbetween: [`room`, `user`],\n\t\tcardinality: `1:n`,\n\t},\n\tDEFAULT_USER_IN_ROOM_META,\n)\n\nexport const usersInMyRoomView = selectorFamily<\n\tMutableAtomToken<SetRTX<string>, SetRTXJson<string>>[],\n\tstring\n>({\n\tkey: `usersInMyRoomView`,\n\tget:\n\t\t(username) =>\n\t\t({ find }) => {\n\t\t\treturn [find(usersInRooms.core.findRelatedKeysState, username)]\n\t\t},\n})\n"]}
@@ -1,5 +1,9 @@
1
- import { AtomFamilyToken, ReadableFamilyToken, ReadableToken, AtomToken, TransactionToken } from 'atom.io';
1
+ import * as atom_io from 'atom.io';
2
+ import { AtomFamilyToken, ReadableFamilyToken, ReadableToken, AtomToken, TransactionToken, MutableAtomToken } from 'atom.io';
2
3
  import { Json } from 'atom.io/json';
4
+ import * as atom_io_data from 'atom.io/data';
5
+ import * as atom_io_internal from 'atom.io/internal';
6
+ import { SetRTX, SetRTXJson } from 'atom.io/transceivers/set-rtx';
3
7
 
4
8
  declare class InvariantMap<K, V> extends Map<K, V> {
5
9
  set(key: K, value: V): this;
@@ -8,7 +12,7 @@ declare class InvariantMap<K, V> extends Map<K, V> {
8
12
  type PerspectiveToken<F extends AtomFamilyToken<any>, T extends F extends AtomFamilyToken<infer T, any> ? T : never> = {
9
13
  type: `realtime_perspective`;
10
14
  resourceAtoms: F;
11
- perspectiveAtoms: ReadableFamilyToken<Iterable<ReadableToken<T>>, string>;
15
+ viewAtoms: ReadableFamilyToken<ReadableToken<T>[], string>;
12
16
  };
13
17
  type ContinuityToken = {
14
18
  readonly type: `continuity`;
@@ -36,4 +40,107 @@ type ContinuityOptions = {
36
40
  };
37
41
  declare function continuity(options: ContinuityOptions): ContinuityToken;
38
42
 
39
- export { type ContinuityOptions, type ContinuityToken, InvariantMap, type PerspectiveToken, SyncGroup, continuity };
43
+ type primitive = boolean | number | string | null;
44
+
45
+ type Serializable = primitive | Readonly<{
46
+ [key: string]: Serializable;
47
+ }> | ReadonlyArray<Serializable>;
48
+ type Object$1<Key extends string = string, Value extends Serializable = Serializable> = Record<Key, Value>;
49
+
50
+ type Refinement<Unrefined, Refined extends Unrefined> = (value: Unrefined) => value is Refined;
51
+ type Cardinality = `1:1` | `1:n` | `n:n`;
52
+
53
+ interface JunctionEntries<Content extends Object$1 | null> extends Object$1 {
54
+ readonly relations: [string, string[]][];
55
+ readonly contents: [string, Content][];
56
+ }
57
+ interface JunctionSchema<ASide extends string, BSide extends string> extends Object$1 {
58
+ readonly between: [a: ASide, b: BSide];
59
+ readonly cardinality: Cardinality;
60
+ }
61
+ type BaseExternalStoreConfiguration = {
62
+ addRelation: (a: string, b: string) => void;
63
+ deleteRelation: (a: string, b: string) => void;
64
+ replaceRelationsSafely: (a: string, bs: string[]) => void;
65
+ replaceRelationsUnsafely: (a: string, bs: string[]) => void;
66
+ getRelatedKeys: (key: string) => Set<string> | undefined;
67
+ has: (a: string, b?: string) => boolean;
68
+ };
69
+ type ExternalStoreWithContentConfiguration<Content extends Object$1> = {
70
+ getContent: (contentKey: string) => Content | undefined;
71
+ setContent: (contentKey: string, content: Content) => void;
72
+ deleteContent: (contentKey: string) => void;
73
+ };
74
+ type Empty<Obj extends object> = {
75
+ [Key in keyof Obj]?: undefined;
76
+ };
77
+ type ExternalStoreConfiguration<Content extends Object$1 | null> = Content extends Object$1 ? BaseExternalStoreConfiguration & ExternalStoreWithContentConfiguration<Content> : BaseExternalStoreConfiguration & Empty<ExternalStoreWithContentConfiguration<Object$1>>;
78
+ type JunctionAdvancedConfiguration<Content extends Object$1 | null> = {
79
+ externalStore?: ExternalStoreConfiguration<Content>;
80
+ isContent?: Refinement<unknown, Content>;
81
+ makeContentKey?: (a: string, b: string) => string;
82
+ };
83
+ type JunctionJSON<ASide extends string, BSide extends string, Content extends Object$1 | null> = JunctionEntries<Content> & JunctionSchema<ASide, BSide>;
84
+ declare class Junction<const ASide extends string, const BSide extends string, const Content extends Object$1 | null = null> {
85
+ readonly a: ASide;
86
+ readonly b: BSide;
87
+ readonly cardinality: Cardinality;
88
+ readonly relations: Map<string, Set<string>>;
89
+ readonly contents: Map<string, Content>;
90
+ isContent: Refinement<unknown, Content> | null;
91
+ makeContentKey: (a: string, b: string) => string;
92
+ getRelatedKeys(key: string): Set<string> | undefined;
93
+ protected addRelation(a: string, b: string): void;
94
+ protected deleteRelation(a: string, b: string): void;
95
+ protected replaceRelationsUnsafely(a: string, bs: string[]): void;
96
+ protected replaceRelationsSafely(a: string, bs: string[]): void;
97
+ protected getContentInternal(contentKey: string): Content | undefined;
98
+ protected setContent(contentKey: string, content: Content): void;
99
+ protected deleteContent(contentKey: string): void;
100
+ constructor(data: JunctionSchema<ASide, BSide> & Partial<JunctionEntries<Content>>, config?: JunctionAdvancedConfiguration<Content>);
101
+ toJSON(): JunctionJSON<ASide, BSide, Content>;
102
+ set(a: string, ...rest: Content extends null ? [b: string] : [b: string, content: Content]): this;
103
+ set(relation: {
104
+ [Key in ASide | BSide]: string;
105
+ }, ...rest: Content extends null ? [] | [b?: undefined] : [content: Content]): this;
106
+ delete(a: string, b?: string): this;
107
+ delete(relation: Record<ASide | BSide, string> | Record<ASide, string> | Record<BSide, string>, b?: undefined): this;
108
+ getRelatedKey(key: string): string | undefined;
109
+ replaceRelations(a: string, relations: Content extends null ? string[] : Record<string, Content>, config?: {
110
+ reckless: boolean;
111
+ }): this;
112
+ getContent(a: string, b: string): Content | undefined;
113
+ getRelationEntries(input: Record<ASide, string> | Record<BSide, string>): [string, Content][];
114
+ has(a: string, b?: string): boolean;
115
+ }
116
+
117
+ declare const usersInThisRoomIndex: MutableAtomToken<SetRTX<string>, SetRTXJson<string>>;
118
+ declare const roomIndex: MutableAtomToken<SetRTX<string>, SetRTXJson<string>>;
119
+ type UserInRoomMeta = {
120
+ enteredAtEpoch: number;
121
+ };
122
+ declare const DEFAULT_USER_IN_ROOM_META: UserInRoomMeta;
123
+ declare const usersInRooms: {
124
+ readonly relations: Junction<"room", "user", UserInRoomMeta>;
125
+ readonly states: {
126
+ readonly roomEntryOfUser: atom_io.ReadonlySelectorFamily<[string, UserInRoomMeta] | null, string>;
127
+ } & {
128
+ readonly userEntriesOfRoom: atom_io.ReadonlySelectorFamily<[string, UserInRoomMeta][], string>;
129
+ } & {
130
+ readonly roomKeyOfUser: atom_io.ReadonlySelectorFamily<string | null, string>;
131
+ } & {
132
+ readonly userKeysOfRoom: atom_io.ReadonlySelectorFamily<string[], string>;
133
+ };
134
+ readonly in: (store: atom_io_internal.Store) => atom_io_data.Join<"room", "user", "1:n", UserInRoomMeta>;
135
+ readonly transact: (transactors: Readonly<{
136
+ get: <S>(state: atom_io.ReadonlySelectorToken<S> | atom_io.WritableToken<S>) => S;
137
+ set: <S_1, New extends S_1>(state: atom_io.WritableToken<S_1>, newValue: New | ((oldValue: S_1) => New)) => void;
138
+ find: typeof atom_io.findState;
139
+ }>, run: (join: atom_io_data.Join<"room", "user", "1:n", UserInRoomMeta>) => void) => void;
140
+ readonly core: {
141
+ readonly findRelatedKeysState: atom_io.MutableAtomFamily<SetRTX<string>, SetRTXJson<string>, string>;
142
+ };
143
+ };
144
+ declare const usersInMyRoomView: atom_io.ReadonlySelectorFamilyTokenWithCall<MutableAtomToken<SetRTX<string>, SetRTXJson<string>>[], string>;
145
+
146
+ export { type ContinuityOptions, type ContinuityToken, DEFAULT_USER_IN_ROOM_META, InvariantMap, type PerspectiveToken, SyncGroup, type UserInRoomMeta, continuity, roomIndex, usersInMyRoomView, usersInRooms, usersInThisRoomIndex };
@@ -1,5 +1,8 @@
1
1
  import '../../dist/chunk-PZLG2HP3.js';
2
- import { assignTransactionToContinuity, IMPLICIT, setEpochNumberOfContinuity } from 'atom.io/internal';
2
+ import { assignTransactionToContinuity, IMPLICIT, setEpochNumberOfContinuity, getUpdateToken } from 'atom.io/internal';
3
+ import { atom, selectorFamily } from 'atom.io';
4
+ import { join } from 'atom.io/data';
5
+ import { SetRTX } from 'atom.io/transceivers/set-rtx';
3
6
 
4
7
  var InvariantMap = class extends Map {
5
8
  set(key, value) {
@@ -35,7 +38,16 @@ var _SyncGroup = class _SyncGroup {
35
38
  const zeroth = args[0];
36
39
  if (zeroth.type === `atom` || zeroth.type === `mutable_atom`) {
37
40
  const globals = args;
38
- this.globals.push(...globals);
41
+ for (const global of globals) {
42
+ switch (global.type) {
43
+ case `atom`:
44
+ this.globals.push(global);
45
+ break;
46
+ case `mutable_atom`:
47
+ this.globals.push(getUpdateToken(global));
48
+ break;
49
+ }
50
+ }
39
51
  } else if (zeroth.type === `transaction`) {
40
52
  const actions = args;
41
53
  this.actions.push(...actions);
@@ -44,7 +56,7 @@ var _SyncGroup = class _SyncGroup {
44
56
  this.perspectives.push({
45
57
  type: `realtime_perspective`,
46
58
  resourceAtoms: family,
47
- perspectiveAtoms: index
59
+ viewAtoms: index
48
60
  });
49
61
  }
50
62
  return this;
@@ -62,7 +74,38 @@ function continuity(options) {
62
74
  setEpochNumberOfContinuity(key, -1, IMPLICIT.STORE);
63
75
  return token;
64
76
  }
77
+ var usersInThisRoomIndex = atom({
78
+ key: `usersInRoomIndex`,
79
+ mutable: true,
80
+ default: () => new SetRTX(),
81
+ toJson: (set) => set.toJSON(),
82
+ fromJson: (json) => SetRTX.fromJSON(json)
83
+ });
84
+ var roomIndex = atom({
85
+ key: `roomIndex`,
86
+ default: () => new SetRTX(),
87
+ mutable: true,
88
+ toJson: (set) => set.toJSON(),
89
+ fromJson: (json) => SetRTX.fromJSON(json)
90
+ });
91
+ var DEFAULT_USER_IN_ROOM_META = {
92
+ enteredAtEpoch: 0
93
+ };
94
+ var usersInRooms = join(
95
+ {
96
+ key: `usersInRooms`,
97
+ between: [`room`, `user`],
98
+ cardinality: `1:n`
99
+ },
100
+ DEFAULT_USER_IN_ROOM_META
101
+ );
102
+ var usersInMyRoomView = selectorFamily({
103
+ key: `usersInMyRoomView`,
104
+ get: (username) => ({ find }) => {
105
+ return [find(usersInRooms.core.findRelatedKeysState, username)];
106
+ }
107
+ });
65
108
 
66
- export { InvariantMap, SyncGroup, continuity };
109
+ export { DEFAULT_USER_IN_ROOM_META, InvariantMap, SyncGroup, continuity, roomIndex, usersInMyRoomView, usersInRooms, usersInThisRoomIndex };
67
110
  //# sourceMappingURL=out.js.map
68
111
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/realtime-continuity.ts"],"names":[],"mappings":";;;AAOA;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,OACM;AAGA,IAAM,eAAN,cAAiC,IAAU;AAAA,EAC1C,IAAI,KAAQ,OAAgB;AAClC,QAAI,KAAK,IAAI,GAAG,GAAG;AAClB,cAAQ,KAAK,6DAA6D;AAAA,QACzE;AAAA,QACA;AAAA,MACD,CAAC;AACD,aAAO;AAAA,IACR;AACA,WAAO,MAAM,IAAI,KAAK,KAAK;AAAA,EAC5B;AAAA,EAEO,QAAc;AACpB,UAAM,IAAI,MAAM,8BAA8B;AAAA,EAC/C;AACD;AAsBO,IAAM,aAAN,MAAM,WAAU;AAAA,EAOZ,YAA+B,KAAa;AAAb;AANzC,SAAU,OAAO;AAEjB,SAAU,UAA4B,CAAC;AACvC,SAAU,UAAmC,CAAC;AAC9C,SAAU,eAA6C,CAAC;AAAA,EAED;AAAA,EAIvD,OAAc,OACb,KACA,SACkB;AAClB,UAAM,QAAQ,IAAI,WAAU,GAAG;AAC/B,UAAM,EAAE,MAAM,SAAS,SAAS,aAAa,IAAI,QAAQ,KAAK;AAC9D,UAAM,QAAQ,EAAE,MAAM,KAAK,SAAS,SAAS,aAAa;AAC1D,eAAU,SAAS,IAAI,KAAK,KAAK;AACjC,WAAO;AAAA,EACR;AAAA,EAWO,OACH,MAIS;AACZ,UAAM,SAAS,KAAK,CAAC;AACrB,QAAI,OAAO,SAAS,UAAU,OAAO,SAAS,gBAAgB;AAC7D,YAAM,UAAU;AAChB,WAAK,QAAQ,KAAK,GAAG,OAAO;AAAA,IAC7B,WAAW,OAAO,SAAS,eAAe;AACzC,YAAM,UAAU;AAChB,WAAK,QAAQ,KAAK,GAAG,OAAO;AAAA,IAC7B,OAAO;AACN,YAAM,CAAC,QAAQ,KAAK,IAAI;AAIxB,WAAK,aAAa,KAAK;AAAA,QACtB,MAAM;AAAA,QACN,eAAe;AAAA,QACf,kBAAkB;AAAA,MACnB,CAAC;AAAA,IACF;AACA,WAAO;AAAA,EACR;AACD;AAzDa,WASE,WACb,IAAI,aAAa;AAVZ,IAAM,YAAN;AAgEA,SAAS,WAAW,SAA6C;AACvE,QAAM,EAAE,KAAK,OAAO,IAAI;AACxB,QAAM,QAAQ,UAAU,OAAO,KAAK,MAAM;AAC1C,QAAM,EAAE,QAAQ,IAAI;AACpB,aAAW,UAAU,SAAS;AAC7B,kCAA8B,KAAK,OAAO,KAAK,SAAS,KAAK;AAAA,EAC9D;AACA,6BAA2B,KAAK,IAAI,SAAS,KAAK;AAClD,SAAO;AACR","sourcesContent":["import type {\n\tAtomFamilyToken,\n\tAtomToken,\n\tReadableFamilyToken,\n\tReadableToken,\n\tTransactionToken,\n} from \"atom.io\"\nimport {\n\tIMPLICIT,\n\tassignTransactionToContinuity,\n\tsetEpochNumberOfContinuity,\n} from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\n\nexport class InvariantMap<K, V> extends Map<K, V> {\n\tpublic set(key: K, value: V): this {\n\t\tif (this.has(key)) {\n\t\t\tconsole.warn(`Tried to set a key that already exists in an InvariantMap`, {\n\t\t\t\tkey,\n\t\t\t\tvalue,\n\t\t\t})\n\t\t\treturn this\n\t\t}\n\t\treturn super.set(key, value)\n\t}\n\n\tpublic clear(): void {\n\t\tthrow new Error(`Cannot clear an InvariantMap`)\n\t}\n}\n\nexport type PerspectiveToken<\n\tF extends AtomFamilyToken<any>,\n\tT extends F extends AtomFamilyToken<infer T, any> ? T : never,\n> = {\n\ttype: `realtime_perspective`\n\tresourceAtoms: F\n\tperspectiveAtoms: ReadableFamilyToken<Iterable<ReadableToken<T>>, string>\n}\n\nexport type ContinuityToken = {\n\treadonly type: `continuity`\n\treadonly key: string\n\treadonly globals: AtomToken<any>[]\n\treadonly actions: TransactionToken<any>[]\n\treadonly perspectives: PerspectiveToken<\n\t\tAtomFamilyToken<any, Json.Serializable>,\n\t\tJson.Serializable\n\t>[]\n}\n\nexport class SyncGroup {\n\tprotected type = `continuity` as const\n\n\tprotected globals: AtomToken<any>[] = []\n\tprotected actions: TransactionToken<any>[] = []\n\tprotected perspectives: PerspectiveToken<any, any>[] = []\n\n\tprotected constructor(protected readonly key: string) {}\n\n\tpublic static existing: InvariantMap<string, ContinuityToken> =\n\t\tnew InvariantMap()\n\tpublic static create(\n\t\tkey: string,\n\t\tbuilder: (group: SyncGroup) => SyncGroup,\n\t): ContinuityToken {\n\t\tconst group = new SyncGroup(key)\n\t\tconst { type, globals, actions, perspectives } = builder(group)\n\t\tconst token = { type, key, globals, actions, perspectives }\n\t\tSyncGroup.existing.set(key, token)\n\t\treturn token\n\t}\n\n\tpublic add(...atoms: AtomToken<any>[]): SyncGroup\n\tpublic add(...args: TransactionToken<any>[]): SyncGroup\n\tpublic add<\n\t\tF extends AtomFamilyToken<any>,\n\t\tT extends F extends AtomFamilyToken<infer T> ? T : never,\n\t>(\n\t\tfamily: AtomFamilyToken<T, any>,\n\t\tindex: ReadableFamilyToken<Iterable<AtomToken<T>>, string>,\n\t): SyncGroup\n\tpublic add(\n\t\t...args:\n\t\t\t| readonly AtomToken<any>[]\n\t\t\t| readonly TransactionToken<any>[]\n\t\t\t| [AtomFamilyToken<any, any>, ReadableFamilyToken<Iterable<any>, string>]\n\t): SyncGroup {\n\t\tconst zeroth = args[0]\n\t\tif (zeroth.type === `atom` || zeroth.type === `mutable_atom`) {\n\t\t\tconst globals = args as AtomToken<any>[]\n\t\t\tthis.globals.push(...globals)\n\t\t} else if (zeroth.type === `transaction`) {\n\t\t\tconst actions = args as TransactionToken<any>[]\n\t\t\tthis.actions.push(...actions)\n\t\t} else {\n\t\t\tconst [family, index] = args as [\n\t\t\t\tAtomFamilyToken<any, any>,\n\t\t\t\tReadableFamilyToken<Iterable<any>, string>,\n\t\t\t]\n\t\t\tthis.perspectives.push({\n\t\t\t\ttype: `realtime_perspective`,\n\t\t\t\tresourceAtoms: family,\n\t\t\t\tperspectiveAtoms: index,\n\t\t\t})\n\t\t}\n\t\treturn this\n\t}\n}\n\nexport type ContinuityOptions = {\n\tkey: string\n\tconfig: (group: SyncGroup) => SyncGroup\n}\n\nexport function continuity(options: ContinuityOptions): ContinuityToken {\n\tconst { key, config } = options\n\tconst token = SyncGroup.create(key, config)\n\tconst { actions } = token\n\tfor (const action of actions) {\n\t\tassignTransactionToContinuity(key, action.key, IMPLICIT.STORE)\n\t}\n\tsetEpochNumberOfContinuity(key, -1, IMPLICIT.STORE)\n\treturn token\n}\n\n// const counterStates = atomFamily<number, { c: string }>({\n// \tkey: `counter`,\n// \tdefault: 0,\n// })\n// const counterIndices = atomFamily<{ c: string }[], string>({\n// \tkey: `counterIndex`,\n// \tdefault: [],\n// })\n// const nameStates = atomFamily<number, { n: string }>({\n// \tkey: `name`,\n// \tdefault: 0,\n// })\n// const nameIndices = atomFamily<{ n: string }[], string>({\n// \tkey: `nameIndex`,\n// \tdefault: [],\n// })\n\n// const counterContinuity = continuity({\n// \tkey: `counter`,\n// \tconfig: (group) =>\n// \t\tgroup\n// \t\t\t.add(counterStates, counterIndices)\n// \t\t\t.add(nameStates, nameIndices)\n// \t\t\t.add(nameStates, nameIndices)\n// \t\t\t.add(nameStates, nameIndices),\n// })\n"]}
1
+ {"version":3,"sources":["../src/realtime-continuity.ts","../src/shared-room-store.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tAtomFamilyToken,\n\tAtomToken,\n\tReadableFamilyToken,\n\tReadableToken,\n\tTransactionToken,\n} from \"atom.io\"\nimport {\n\tIMPLICIT,\n\tassignTransactionToContinuity,\n\tgetUpdateToken,\n\tsetEpochNumberOfContinuity,\n} from \"atom.io/internal\"\nimport type { Json } from \"atom.io/json\"\n\nexport class InvariantMap<K, V> extends Map<K, V> {\n\tpublic set(key: K, value: V): this {\n\t\tif (this.has(key)) {\n\t\t\tconsole.warn(`Tried to set a key that already exists in an InvariantMap`, {\n\t\t\t\tkey,\n\t\t\t\tvalue,\n\t\t\t})\n\t\t\treturn this\n\t\t}\n\t\treturn super.set(key, value)\n\t}\n\n\tpublic clear(): void {\n\t\tthrow new Error(`Cannot clear an InvariantMap`)\n\t}\n}\n\nexport type PerspectiveToken<\n\tF extends AtomFamilyToken<any>,\n\tT extends F extends AtomFamilyToken<infer T, any> ? T : never,\n> = {\n\ttype: `realtime_perspective`\n\tresourceAtoms: F\n\tviewAtoms: ReadableFamilyToken<ReadableToken<T>[], string>\n}\n\nexport type ContinuityToken = {\n\treadonly type: `continuity`\n\treadonly key: string\n\treadonly globals: AtomToken<any>[]\n\treadonly actions: TransactionToken<any>[]\n\treadonly perspectives: PerspectiveToken<\n\t\tAtomFamilyToken<any, Json.Serializable>,\n\t\tJson.Serializable\n\t>[]\n}\n\nexport class SyncGroup {\n\tprotected type = `continuity` as const\n\n\tprotected globals: AtomToken<any>[] = []\n\tprotected actions: TransactionToken<any>[] = []\n\tprotected perspectives: PerspectiveToken<any, any>[] = []\n\n\tprotected constructor(protected readonly key: string) {}\n\n\tpublic static existing: InvariantMap<string, ContinuityToken> =\n\t\tnew InvariantMap()\n\tpublic static create(\n\t\tkey: string,\n\t\tbuilder: (group: SyncGroup) => SyncGroup,\n\t): ContinuityToken {\n\t\tconst group = new SyncGroup(key)\n\t\tconst { type, globals, actions, perspectives } = builder(group)\n\t\tconst token = { type, key, globals, actions, perspectives }\n\t\tSyncGroup.existing.set(key, token)\n\t\treturn token\n\t}\n\n\tpublic add(...atoms: AtomToken<any>[]): SyncGroup\n\tpublic add(...args: TransactionToken<any>[]): SyncGroup\n\tpublic add<\n\t\tF extends AtomFamilyToken<any>,\n\t\tT extends F extends AtomFamilyToken<infer T> ? T : never,\n\t>(\n\t\tfamily: AtomFamilyToken<T, any>,\n\t\tindex: ReadableFamilyToken<Iterable<AtomToken<T>>, string>,\n\t): SyncGroup\n\tpublic add(\n\t\t...args:\n\t\t\t| readonly AtomToken<any>[]\n\t\t\t| readonly TransactionToken<any>[]\n\t\t\t| [AtomFamilyToken<any, any>, ReadableFamilyToken<Iterable<any>, string>]\n\t): SyncGroup {\n\t\tconst zeroth = args[0]\n\t\tif (zeroth.type === `atom` || zeroth.type === `mutable_atom`) {\n\t\t\tconst globals = args as AtomToken<any>[]\n\t\t\tfor (const global of globals) {\n\t\t\t\tswitch (global.type) {\n\t\t\t\t\tcase `atom`:\n\t\t\t\t\t\tthis.globals.push(global)\n\t\t\t\t\t\tbreak\n\t\t\t\t\tcase `mutable_atom`:\n\t\t\t\t\t\tthis.globals.push(getUpdateToken(global))\n\t\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (zeroth.type === `transaction`) {\n\t\t\tconst actions = args as TransactionToken<any>[]\n\t\t\tthis.actions.push(...actions)\n\t\t} else {\n\t\t\tconst [family, index] = args as [\n\t\t\t\tAtomFamilyToken<any, any>,\n\t\t\t\tReadableFamilyToken<ReadableToken<any>[], string>,\n\t\t\t]\n\t\t\tthis.perspectives.push({\n\t\t\t\ttype: `realtime_perspective`,\n\t\t\t\tresourceAtoms: family,\n\t\t\t\tviewAtoms: index,\n\t\t\t})\n\t\t}\n\t\treturn this\n\t}\n}\n\nexport type ContinuityOptions = {\n\tkey: string\n\tconfig: (group: SyncGroup) => SyncGroup\n}\n\nexport function continuity(options: ContinuityOptions): ContinuityToken {\n\tconst { key, config } = options\n\tconst token = SyncGroup.create(key, config)\n\tconst { actions } = token\n\tfor (const action of actions) {\n\t\tassignTransactionToContinuity(key, action.key, IMPLICIT.STORE)\n\t}\n\tsetEpochNumberOfContinuity(key, -1, IMPLICIT.STORE)\n\treturn token\n}\n\n// const counterStates = atomFamily<number, { c: string }>({\n// \tkey: `counter`,\n// \tdefault: 0,\n// })\n// const counterIndices = atomFamily<{ c: string }[], string>({\n// \tkey: `counterIndex`,\n// \tdefault: [],\n// })\n// const nameStates = atomFamily<number, { n: string }>({\n// \tkey: `name`,\n// \tdefault: 0,\n// })\n// const nameIndices = atomFamily<{ n: string }[], string>({\n// \tkey: `nameIndex`,\n// \tdefault: [],\n// })\n\n// const counterContinuity = continuity({\n// \tkey: `counter`,\n// \tconfig: (group) =>\n// \t\tgroup\n// \t\t\t.add(counterStates, counterIndices)\n// \t\t\t.add(nameStates, nameIndices)\n// \t\t\t.add(nameStates, nameIndices)\n// \t\t\t.add(nameStates, nameIndices),\n// })\n","import type { MutableAtomToken } from \"atom.io\"\nimport { atom, selectorFamily } from \"atom.io\"\nimport { join } from \"atom.io/data\"\nimport type { SetRTXJson } from \"atom.io/transceivers/set-rtx\"\nimport { SetRTX } from \"atom.io/transceivers/set-rtx\"\n\nexport const usersInThisRoomIndex = atom<SetRTX<string>, SetRTXJson<string>>({\n\tkey: `usersInRoomIndex`,\n\tmutable: true,\n\tdefault: () => new SetRTX<string>(),\n\ttoJson: (set) => set.toJSON(),\n\tfromJson: (json) => SetRTX.fromJSON(json),\n})\n\nexport const roomIndex = atom({\n\tkey: `roomIndex`,\n\tdefault: () => new SetRTX<string>(),\n\tmutable: true,\n\ttoJson: (set) => set.toJSON(),\n\tfromJson: (json) => SetRTX.fromJSON(json),\n})\n\nexport type UserInRoomMeta = {\n\tenteredAtEpoch: number\n}\nexport const DEFAULT_USER_IN_ROOM_META: UserInRoomMeta = {\n\tenteredAtEpoch: 0,\n}\nexport const usersInRooms = join(\n\t{\n\t\tkey: `usersInRooms`,\n\t\tbetween: [`room`, `user`],\n\t\tcardinality: `1:n`,\n\t},\n\tDEFAULT_USER_IN_ROOM_META,\n)\n\nexport const usersInMyRoomView = selectorFamily<\n\tMutableAtomToken<SetRTX<string>, SetRTXJson<string>>[],\n\tstring\n>({\n\tkey: `usersInMyRoomView`,\n\tget:\n\t\t(username) =>\n\t\t({ find }) => {\n\t\t\treturn [find(usersInRooms.core.findRelatedKeysState, username)]\n\t\t},\n})\n"]}
@@ -1 +1,2 @@
1
1
  export * from "./realtime-continuity"
2
+ export * from "./shared-room-store"
@@ -8,6 +8,7 @@ import type {
8
8
  import {
9
9
  IMPLICIT,
10
10
  assignTransactionToContinuity,
11
+ getUpdateToken,
11
12
  setEpochNumberOfContinuity,
12
13
  } from "atom.io/internal"
13
14
  import type { Json } from "atom.io/json"
@@ -35,7 +36,7 @@ export type PerspectiveToken<
35
36
  > = {
36
37
  type: `realtime_perspective`
37
38
  resourceAtoms: F
38
- perspectiveAtoms: ReadableFamilyToken<Iterable<ReadableToken<T>>, string>
39
+ viewAtoms: ReadableFamilyToken<ReadableToken<T>[], string>
39
40
  }
40
41
 
41
42
  export type ContinuityToken = {
@@ -89,19 +90,28 @@ export class SyncGroup {
89
90
  const zeroth = args[0]
90
91
  if (zeroth.type === `atom` || zeroth.type === `mutable_atom`) {
91
92
  const globals = args as AtomToken<any>[]
92
- this.globals.push(...globals)
93
+ for (const global of globals) {
94
+ switch (global.type) {
95
+ case `atom`:
96
+ this.globals.push(global)
97
+ break
98
+ case `mutable_atom`:
99
+ this.globals.push(getUpdateToken(global))
100
+ break
101
+ }
102
+ }
93
103
  } else if (zeroth.type === `transaction`) {
94
104
  const actions = args as TransactionToken<any>[]
95
105
  this.actions.push(...actions)
96
106
  } else {
97
107
  const [family, index] = args as [
98
108
  AtomFamilyToken<any, any>,
99
- ReadableFamilyToken<Iterable<any>, string>,
109
+ ReadableFamilyToken<ReadableToken<any>[], string>,
100
110
  ]
101
111
  this.perspectives.push({
102
112
  type: `realtime_perspective`,
103
113
  resourceAtoms: family,
104
- perspectiveAtoms: index,
114
+ viewAtoms: index,
105
115
  })
106
116
  }
107
117
  return this
@@ -0,0 +1,48 @@
1
+ import type { MutableAtomToken } from "atom.io"
2
+ import { atom, selectorFamily } from "atom.io"
3
+ import { join } from "atom.io/data"
4
+ import type { SetRTXJson } from "atom.io/transceivers/set-rtx"
5
+ import { SetRTX } from "atom.io/transceivers/set-rtx"
6
+
7
+ export const usersInThisRoomIndex = atom<SetRTX<string>, SetRTXJson<string>>({
8
+ key: `usersInRoomIndex`,
9
+ mutable: true,
10
+ default: () => new SetRTX<string>(),
11
+ toJson: (set) => set.toJSON(),
12
+ fromJson: (json) => SetRTX.fromJSON(json),
13
+ })
14
+
15
+ export const roomIndex = atom({
16
+ key: `roomIndex`,
17
+ default: () => new SetRTX<string>(),
18
+ mutable: true,
19
+ toJson: (set) => set.toJSON(),
20
+ fromJson: (json) => SetRTX.fromJSON(json),
21
+ })
22
+
23
+ export type UserInRoomMeta = {
24
+ enteredAtEpoch: number
25
+ }
26
+ export const DEFAULT_USER_IN_ROOM_META: UserInRoomMeta = {
27
+ enteredAtEpoch: 0,
28
+ }
29
+ export const usersInRooms = join(
30
+ {
31
+ key: `usersInRooms`,
32
+ between: [`room`, `user`],
33
+ cardinality: `1:n`,
34
+ },
35
+ DEFAULT_USER_IN_ROOM_META,
36
+ )
37
+
38
+ export const usersInMyRoomView = selectorFamily<
39
+ MutableAtomToken<SetRTX<string>, SetRTXJson<string>>[],
40
+ string
41
+ >({
42
+ key: `usersInMyRoomView`,
43
+ get:
44
+ (username) =>
45
+ ({ find }) => {
46
+ return [find(usersInRooms.core.findRelatedKeysState, username)]
47
+ },
48
+ })