@peers-app/peers-sdk 0.14.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (210) hide show
  1. package/dist/context/data-context.d.ts +4 -4
  2. package/dist/context/data-context.js +1 -1
  3. package/dist/context/index.d.ts +3 -3
  4. package/dist/context/index.js +4 -0
  5. package/dist/context/user-context-singleton.js +13 -14
  6. package/dist/context/user-context.d.ts +4 -4
  7. package/dist/context/user-context.js +48 -31
  8. package/dist/data/assistants.d.ts +1 -1
  9. package/dist/data/assistants.js +35 -24
  10. package/dist/data/change-tracking.d.ts +8 -8
  11. package/dist/data/change-tracking.js +45 -39
  12. package/dist/data/channels.js +5 -5
  13. package/dist/data/data-locks.d.ts +2 -2
  14. package/dist/data/data-locks.js +21 -23
  15. package/dist/data/data-locks.test.js +73 -75
  16. package/dist/data/device-sync-info.d.ts +1 -1
  17. package/dist/data/device-sync-info.js +4 -4
  18. package/dist/data/devices.d.ts +1 -1
  19. package/dist/data/devices.js +9 -12
  20. package/dist/data/embeddings.js +14 -11
  21. package/dist/data/files/file-read-stream.d.ts +2 -2
  22. package/dist/data/files/file-read-stream.js +23 -14
  23. package/dist/data/files/file-write-stream.d.ts +2 -2
  24. package/dist/data/files/file-write-stream.js +8 -8
  25. package/dist/data/files/file.types.d.ts +2 -2
  26. package/dist/data/files/file.types.js +17 -11
  27. package/dist/data/files/files.d.ts +6 -6
  28. package/dist/data/files/files.js +17 -19
  29. package/dist/data/files/files.test.js +213 -214
  30. package/dist/data/files/index.d.ts +4 -4
  31. package/dist/data/files/index.js +4 -4
  32. package/dist/data/group-member-roles.js +2 -2
  33. package/dist/data/group-members.d.ts +5 -5
  34. package/dist/data/group-members.js +27 -18
  35. package/dist/data/group-members.test.js +73 -73
  36. package/dist/data/group-permissions.d.ts +3 -3
  37. package/dist/data/group-permissions.js +13 -11
  38. package/dist/data/group-share.d.ts +2 -2
  39. package/dist/data/group-share.js +29 -24
  40. package/dist/data/groups.d.ts +4 -4
  41. package/dist/data/groups.js +27 -19
  42. package/dist/data/groups.test.js +44 -44
  43. package/dist/data/index.d.ts +6 -6
  44. package/dist/data/index.js +6 -6
  45. package/dist/data/knowledge/peer-types.js +9 -9
  46. package/dist/data/messages.d.ts +5 -5
  47. package/dist/data/messages.js +43 -30
  48. package/dist/data/orm/client-proxy.data-source.d.ts +4 -4
  49. package/dist/data/orm/client-proxy.data-source.js +10 -12
  50. package/dist/data/orm/cursor.d.ts +1 -1
  51. package/dist/data/orm/cursor.js +2 -2
  52. package/dist/data/orm/cursor.test.js +92 -93
  53. package/dist/data/orm/data-query.d.ts +3 -3
  54. package/dist/data/orm/data-query.js +24 -18
  55. package/dist/data/orm/data-query.mongo.d.ts +1 -1
  56. package/dist/data/orm/data-query.mongo.js +49 -51
  57. package/dist/data/orm/data-query.mongo.test.js +173 -204
  58. package/dist/data/orm/data-query.sqlite.d.ts +1 -1
  59. package/dist/data/orm/data-query.sqlite.js +84 -73
  60. package/dist/data/orm/data-query.sqlite.test.js +164 -176
  61. package/dist/data/orm/data-query.test.js +216 -224
  62. package/dist/data/orm/decorators.js +3 -3
  63. package/dist/data/orm/dependency-injection.test.js +53 -56
  64. package/dist/data/orm/doc.d.ts +4 -4
  65. package/dist/data/orm/doc.js +17 -21
  66. package/dist/data/orm/event-registry.d.ts +1 -1
  67. package/dist/data/orm/event-registry.test.js +16 -16
  68. package/dist/data/orm/factory.d.ts +2 -2
  69. package/dist/data/orm/factory.js +33 -33
  70. package/dist/data/orm/index.d.ts +10 -10
  71. package/dist/data/orm/index.js +10 -10
  72. package/dist/data/orm/multi-cursors.d.ts +1 -1
  73. package/dist/data/orm/multi-cursors.js +6 -6
  74. package/dist/data/orm/multi-cursors.test.js +152 -144
  75. package/dist/data/orm/sql.data-source.d.ts +7 -7
  76. package/dist/data/orm/sql.data-source.js +88 -93
  77. package/dist/data/orm/sql.data-source.test.js +109 -101
  78. package/dist/data/orm/subscribable.data-source.d.ts +4 -4
  79. package/dist/data/orm/subscribable.data-source.js +5 -5
  80. package/dist/data/orm/table-container-events.test.js +34 -26
  81. package/dist/data/orm/table-container.d.ts +6 -6
  82. package/dist/data/orm/table-container.js +33 -21
  83. package/dist/data/orm/table-container.test.js +64 -53
  84. package/dist/data/orm/table-definitions.system.d.ts +3 -3
  85. package/dist/data/orm/table-definitions.system.js +3 -3
  86. package/dist/data/orm/table-definitions.type.d.ts +5 -5
  87. package/dist/data/orm/table-dependencies.d.ts +2 -2
  88. package/dist/data/orm/table.d.ts +5 -5
  89. package/dist/data/orm/table.event-source.test.js +105 -115
  90. package/dist/data/orm/table.js +35 -34
  91. package/dist/data/orm/types.d.ts +3 -3
  92. package/dist/data/orm/types.js +26 -25
  93. package/dist/data/orm/types.test.js +166 -92
  94. package/dist/data/package-permissions.d.ts +1 -1
  95. package/dist/data/package-permissions.js +2 -2
  96. package/dist/data/package-version-permissions.d.ts +1 -1
  97. package/dist/data/package-version-permissions.js +2 -2
  98. package/dist/data/package-versions.d.ts +9 -9
  99. package/dist/data/package-versions.js +47 -33
  100. package/dist/data/packages.d.ts +2 -2
  101. package/dist/data/packages.js +36 -18
  102. package/dist/data/packages.utils.d.ts +2 -2
  103. package/dist/data/packages.utils.js +4 -4
  104. package/dist/data/persistent-vars.d.ts +15 -15
  105. package/dist/data/persistent-vars.js +165 -154
  106. package/dist/data/table-definitions-table.d.ts +5 -5
  107. package/dist/data/table-definitions-table.js +13 -12
  108. package/dist/data/tool-tests.js +6 -6
  109. package/dist/data/tools.js +29 -19
  110. package/dist/data/user-permissions.d.ts +1 -1
  111. package/dist/data/user-permissions.js +5 -5
  112. package/dist/data/user-permissions.test.js +90 -88
  113. package/dist/data/user-trust-levels.js +10 -10
  114. package/dist/data/users.d.ts +4 -4
  115. package/dist/data/users.js +16 -15
  116. package/dist/data/voice-messages.d.ts +2 -2
  117. package/dist/data/voice-messages.js +13 -13
  118. package/dist/data/welcome-modal.pvar.js +3 -1
  119. package/dist/data/workflow-logs.js +26 -18
  120. package/dist/data/workflow-runs.d.ts +6 -6
  121. package/dist/data/workflow-runs.js +70 -44
  122. package/dist/data/workflows.d.ts +2 -2
  123. package/dist/data/workflows.js +7 -9
  124. package/dist/device/binary-peer-connection-v2.d.ts +7 -7
  125. package/dist/device/binary-peer-connection-v2.js +32 -28
  126. package/dist/device/binary-peer-connection-v2.test.js +80 -67
  127. package/dist/device/binary-peer-connection.d.ts +7 -7
  128. package/dist/device/binary-peer-connection.js +29 -28
  129. package/dist/device/binary-peer-connection.test.js +35 -31
  130. package/dist/device/connection.d.ts +5 -5
  131. package/dist/device/connection.js +59 -48
  132. package/dist/device/connection.test.js +74 -68
  133. package/dist/device/device-election.d.ts +2 -2
  134. package/dist/device/device-election.js +25 -20
  135. package/dist/device/device-election.test.js +35 -36
  136. package/dist/device/device.d.ts +2 -2
  137. package/dist/device/device.js +10 -4
  138. package/dist/device/device.test.js +16 -17
  139. package/dist/device/get-trust-level-fn.d.ts +2 -2
  140. package/dist/device/get-trust-level-fn.js +22 -11
  141. package/dist/device/get-trust-level-fn.test.js +58 -58
  142. package/dist/device/socket-io-binary-peer.d.ts +1 -1
  143. package/dist/device/socket-io-binary-peer.js +16 -13
  144. package/dist/device/socket.type.d.ts +2 -2
  145. package/dist/device/streamed-socket.d.ts +2 -2
  146. package/dist/device/streamed-socket.js +8 -8
  147. package/dist/device/streamed-socket.test.js +40 -40
  148. package/dist/device/tx-encoding.test.js +77 -77
  149. package/dist/events.d.ts +1 -1
  150. package/dist/events.js +5 -2
  151. package/dist/group-invite/group-invite.js +110 -19
  152. package/dist/group-invite/group-invite.pvars.d.ts +2 -2
  153. package/dist/group-invite/group-invite.pvars.js +21 -13
  154. package/dist/group-invite/group-invite.types.d.ts +1 -1
  155. package/dist/group-invite/index.d.ts +3 -3
  156. package/dist/group-invite/index.js +1 -1
  157. package/dist/index.d.ts +25 -24
  158. package/dist/index.js +30 -25
  159. package/dist/keys.d.ts +3 -3
  160. package/dist/keys.js +31 -30
  161. package/dist/keys.test.js +69 -61
  162. package/dist/logging/console-logger.d.ts +1 -1
  163. package/dist/logging/console-logger.js +35 -40
  164. package/dist/logging/console-logger.test.js +115 -115
  165. package/dist/logging/console-logs.table.d.ts +3 -3
  166. package/dist/logging/console-logs.table.js +28 -23
  167. package/dist/mentions.js +16 -12
  168. package/dist/observable.d.ts +2 -2
  169. package/dist/observable.js +15 -9
  170. package/dist/observable.test.js +47 -47
  171. package/dist/package-loader/get-require.js +3 -4
  172. package/dist/package-loader/package-loader.d.ts +2 -2
  173. package/dist/package-loader/package-loader.js +52 -34
  174. package/dist/peers-ui/peers-ui.d.ts +2 -2
  175. package/dist/peers-ui/peers-ui.js +2 -4
  176. package/dist/peers-ui/peers-ui.types.d.ts +3 -3
  177. package/dist/peers-ui/peers-ui.types.js +0 -1
  178. package/dist/rpc-types.d.ts +61 -59
  179. package/dist/rpc-types.js +61 -55
  180. package/dist/serial-json.d.ts +1 -1
  181. package/dist/serial-json.js +50 -43
  182. package/dist/serial-json.test.js +22 -22
  183. package/dist/system-ids.js +8 -8
  184. package/dist/tools/index.d.ts +1 -1
  185. package/dist/tools/tools-factory.d.ts +1 -1
  186. package/dist/tools/tools-factory.js +2 -2
  187. package/dist/types/assistant-runner-args.d.ts +3 -3
  188. package/dist/types/peer-device.d.ts +1 -1
  189. package/dist/types/peers-package.d.ts +3 -3
  190. package/dist/types/workflow-logger.d.ts +1 -1
  191. package/dist/types/workflow-run-context.d.ts +4 -4
  192. package/dist/types/workflow.d.ts +4 -4
  193. package/dist/types/workflow.js +27 -14
  194. package/dist/types/zod-types.d.ts +2 -1
  195. package/dist/types/zod-types.js +9 -3
  196. package/dist/user-connect/connection-code.d.ts +1 -1
  197. package/dist/user-connect/connection-code.js +7 -7
  198. package/dist/user-connect/connection-code.test.js +106 -106
  199. package/dist/user-connect/index.d.ts +3 -3
  200. package/dist/user-connect/index.js +1 -1
  201. package/dist/user-connect/user-connect.pvars.js +13 -11
  202. package/dist/user-connect/user-connect.types.d.ts +3 -3
  203. package/dist/users.query.d.ts +2 -2
  204. package/dist/users.query.js +40 -30
  205. package/dist/utils.d.ts +2 -2
  206. package/dist/utils.js +34 -32
  207. package/dist/utils.test.js +12 -8
  208. package/dist/workflow-log-formatter.d.ts +1 -1
  209. package/dist/workflow-log-formatter.js +17 -18
  210. package/package.json +14 -8
@@ -27,24 +27,27 @@ const types_1 = require("./orm/types");
27
27
  const schema = zod_1.z.object({
28
28
  persistentVarId: zod_types_1.zodPeerId,
29
29
  name: zod_1.z.string(),
30
- scope: zod_1.z.enum(['device', 'user', 'group', 'groupDevice', 'groupUser']),
31
- value: zod_1.z.object({
30
+ scope: zod_1.z.enum(["device", "user", "group", "groupDevice", "groupUser"]),
31
+ value: zod_1.z
32
+ .object({
32
33
  value: zod_1.z.any(),
33
- }).describe('The value of the persistent variable encoded as JSON'),
34
+ })
35
+ .describe("The value of the persistent variable encoded as JSON"),
34
36
  description: zod_1.z.string().optional(),
35
37
  userCreated: zod_1.z.boolean().optional(),
36
38
  isSecret: zod_1.z.boolean().optional(),
37
- modifiedAt: zod_1.z.number().optional().describe('Timestamp of when this pvar was last modified (Date.now())'),
39
+ modifiedAt: zod_1.z
40
+ .number()
41
+ .optional()
42
+ .describe("Timestamp of when this pvar was last modified (Date.now())"),
38
43
  });
39
44
  exports.persistentVarsMetaData = {
40
- name: 'PersistentVars',
41
- description: 'table to persist variables across sessions and devices',
42
- primaryKeyName: 'persistentVarId',
45
+ name: "PersistentVars",
46
+ description: "table to persist variables across sessions and devices",
47
+ primaryKeyName: "persistentVarId",
43
48
  fields: (0, types_1.schemaToFields)(schema),
44
- iconClassName: 'bi bi-braces',
45
- indexes: [
46
- { fields: ['name'], unique: true },
47
- ]
49
+ iconClassName: "bi bi-braces",
50
+ indexes: [{ fields: ["name"], unique: true }],
48
51
  };
49
52
  class PersistentVarsTable extends table_1.Table {
50
53
  async insert(persistentVar) {
@@ -59,8 +62,10 @@ class PersistentVarsTable extends table_1.Table {
59
62
  }
60
63
  const dbVar = await this.get(persistentVar.persistentVarId);
61
64
  if (persistentVar.isSecret && persistentVar.value.value !== undefined && !rpc_types_1.isClient) {
62
- if (!dbVar || dbVar.value.value !== persistentVar.value.value || dbVar.isSecret !== persistentVar.isSecret) {
63
- persistentVar.value.value = await rpc_types_1.rpcServerCalls.encryptData(persistentVar.value.value || '', this.groupId);
65
+ if (!dbVar ||
66
+ dbVar.value.value !== persistentVar.value.value ||
67
+ dbVar.isSecret !== persistentVar.isSecret) {
68
+ persistentVar.value.value = await rpc_types_1.rpcServerCalls.encryptData(persistentVar.value.value || "", this.groupId);
64
69
  }
65
70
  }
66
71
  persistentVar.modifiedAt = Date.now();
@@ -87,7 +92,7 @@ async function getPersistentVar(name, dataContext) {
87
92
  if (!pVars.length) {
88
93
  return undefined;
89
94
  }
90
- const pVarDevice = pVars.find(pVar => pVar.scope === 'device');
95
+ const pVarDevice = pVars.find((pVar) => pVar.scope === "device");
91
96
  if (pVarDevice) {
92
97
  return pVarDevice;
93
98
  }
@@ -96,7 +101,7 @@ async function getPersistentVar(name, dataContext) {
96
101
  /** Cache for pvar instances keyed by scope:name:userContextId:dataContextId */
97
102
  const pvarCache = new Map();
98
103
  function deviceVar(name, opts) {
99
- const fullOpts = { ...opts, scope: 'device' };
104
+ const fullOpts = { ...opts, scope: "device" };
100
105
  if (opts?.defaultValue !== undefined) {
101
106
  return persistentVarFactory(name, fullOpts);
102
107
  }
@@ -105,7 +110,7 @@ function deviceVar(name, opts) {
105
110
  }
106
111
  }
107
112
  function userVar(name, opts) {
108
- const fullOpts = { ...opts, scope: 'user' };
113
+ const fullOpts = { ...opts, scope: "user" };
109
114
  if (opts?.defaultValue !== undefined) {
110
115
  return persistentVarFactory(name, fullOpts);
111
116
  }
@@ -114,7 +119,7 @@ function userVar(name, opts) {
114
119
  }
115
120
  }
116
121
  function groupVar(name, opts) {
117
- const fullOpts = { ...opts, scope: 'group' };
122
+ const fullOpts = { ...opts, scope: "group" };
118
123
  if (opts?.defaultValue !== undefined) {
119
124
  return persistentVarFactory(name, fullOpts);
120
125
  }
@@ -123,7 +128,7 @@ function groupVar(name, opts) {
123
128
  }
124
129
  }
125
130
  function groupDeviceVar(name, opts) {
126
- const fullOpts = { ...opts, scope: 'groupDevice' };
131
+ const fullOpts = { ...opts, scope: "groupDevice" };
127
132
  if (opts?.defaultValue !== undefined) {
128
133
  return persistentVarFactory(name, fullOpts);
129
134
  }
@@ -132,7 +137,7 @@ function groupDeviceVar(name, opts) {
132
137
  }
133
138
  }
134
139
  function groupUserVar(name, opts) {
135
- const fullOpts = { ...opts, scope: 'groupUser' };
140
+ const fullOpts = { ...opts, scope: "groupUser" };
136
141
  if (opts?.defaultValue !== undefined) {
137
142
  return persistentVarFactory(name, fullOpts);
138
143
  }
@@ -141,22 +146,22 @@ function groupUserVar(name, opts) {
141
146
  }
142
147
  }
143
148
  function persistentVarFactory(name, opts) {
144
- const scope = opts.scope || 'device';
149
+ const scope = opts.scope || "device";
145
150
  // Check cache - key is based on the parameters passed in
146
- const cacheKey = `${scope}:${name}:${opts?.userContext?.userId ?? ''}:${opts?.dataContext?.dataContextId ?? ''}`;
151
+ const cacheKey = `${scope}:${name}:${opts?.userContext?.userId ?? ""}:${opts?.dataContext?.dataContextId ?? ""}`;
147
152
  const cached = pvarCache.get(cacheKey);
148
153
  if (cached) {
149
154
  return cached;
150
155
  }
151
- const setWithDbValue = Object.keys(opts ?? {}).includes('dbValue');
156
+ const setWithDbValue = Object.keys(opts ?? {}).includes("dbValue");
152
157
  const defaultValue = opts?.defaultValue;
153
158
  const initialValue = setWithDbValue ? opts?.dbValue : defaultValue;
154
159
  const persistentVar = (initialValue !== undefined ? (0, observable_1.observable)(initialValue) : (0, observable_1.observable)());
155
160
  // Cache immediately
156
161
  pvarCache.set(cacheKey, persistentVar);
157
162
  let isSecret = opts.isSecret;
158
- let rec = undefined;
159
- let deleteVarImpl = undefined;
163
+ let rec;
164
+ let deleteVarImpl;
160
165
  // Assign the delete method - it will wait for loading and then call the implementation
161
166
  persistentVar.delete = async () => {
162
167
  await persistentVar.loadingPromise;
@@ -164,155 +169,161 @@ function persistentVarFactory(name, opts) {
164
169
  await deleteVarImpl();
165
170
  }
166
171
  };
167
- persistentVar.loadingPromise = new Promise(async (resolve) => {
168
- try {
169
- const userContext = opts?.userContext || await (0, user_context_singleton_1.getUserContext)();
170
- function getDataContext() {
171
- if (opts?.dataContext) {
172
- return opts.dataContext;
173
- }
174
- if (scope === 'group') {
175
- return userContext.defaultDataContext();
176
- }
177
- else {
178
- return userContext.userDataContext;
179
- }
180
- }
181
- function getVarNameInDb() {
182
- if (scope === 'groupDevice' || scope === 'groupUser') {
183
- const dc = opts?.dataContext || userContext.defaultDataContext();
184
- // if it's a group var saved in the user's personal db, it's postfixed with the dataContextId to make it unique
185
- return name + `_` + dc.dataContextId;
186
- }
187
- return name;
188
- }
189
- async function loadRecFromDb() {
190
- const dc = getDataContext();
191
- const table = PersistentVars(dc);
192
- const name = getVarNameInDb();
193
- let dbRec = await table.findOne({ name });
194
- if (dbRec) {
195
- if (dbRec.scope !== scope) {
196
- console.warn(`${name}: deleting old persistent var record because scopes don't match. If this is unexpected there could be two different persistent variables using the same name`);
197
- await table.delete(dbRec);
198
- dbRec = undefined;
172
+ persistentVar.loadingPromise = new Promise((resolve) => {
173
+ void (async () => {
174
+ try {
175
+ const userContext = opts?.userContext || (await (0, user_context_singleton_1.getUserContext)());
176
+ function getDataContext() {
177
+ if (opts?.dataContext) {
178
+ return opts.dataContext;
179
+ }
180
+ if (scope === "group") {
181
+ return userContext.defaultDataContext();
182
+ }
183
+ else {
184
+ return userContext.userDataContext;
199
185
  }
200
186
  }
201
- if (!dbRec) {
202
- dbRec = {
203
- persistentVarId: '',
204
- name,
205
- scope,
206
- isSecret,
207
- value: { value: defaultValue },
208
- };
209
- }
210
- // if the db says it's secret but the caller didn't specify, assume it's secret
211
- if (dbRec.isSecret !== undefined && opts.isSecret === undefined) {
212
- isSecret = dbRec.isSecret;
213
- }
214
- return dbRec;
215
- }
216
- async function reactToValueChanged(value) {
217
- if (name === 'colorModePreference')
218
- console.log(`colorModePreferences pvar value set: ${value}`);
219
- // Skip if the observable has already moved on to a different value (handles rapid updates)
220
- // This prevents stale writes that could cause infinite update loops between pvar instances
221
- if (!(0, lodash_1.isEqual)(persistentVar(), value)) {
222
- return;
223
- }
224
- if (!rec?.persistentVarId && value === defaultValue) {
225
- return;
226
- }
227
- if (!rec?.persistentVarId) {
228
- rec = await loadRecFromDb();
229
- }
230
- if ((0, lodash_1.isEqual)(value, rec.value.value)) {
231
- return;
187
+ function getVarNameInDb() {
188
+ if (scope === "groupDevice" || scope === "groupUser") {
189
+ const dc = opts?.dataContext || userContext.defaultDataContext();
190
+ // if it's a group var saved in the user's personal db, it's postfixed with the dataContextId to make it unique
191
+ return `${name}_${dc?.dataContextId}`;
192
+ }
193
+ return name;
232
194
  }
233
- rec.value.value = value;
234
- const dc = getDataContext();
235
- const table = PersistentVars(dc);
236
- try {
237
- rec = await table.save(rec);
238
- if (name === 'colorModePreference') {
239
- console.log(`Saved var ${name} to db:`, rec.value.value);
195
+ async function loadRecFromDb() {
196
+ const dc = getDataContext();
197
+ const table = PersistentVars(dc);
198
+ const name = getVarNameInDb();
199
+ let dbRec = await table.findOne({ name });
200
+ if (dbRec) {
201
+ if (dbRec.scope !== scope) {
202
+ console.warn(`${name}: deleting old persistent var record because scopes don't match. If this is unexpected there could be two different persistent variables using the same name`);
203
+ await table.delete(dbRec);
204
+ dbRec = undefined;
205
+ }
206
+ }
207
+ if (!dbRec) {
208
+ dbRec = {
209
+ persistentVarId: "",
210
+ name,
211
+ scope,
212
+ isSecret,
213
+ value: { value: defaultValue },
214
+ };
215
+ }
216
+ // if the db says it's secret but the caller didn't specify, assume it's secret
217
+ if (dbRec.isSecret !== undefined && opts.isSecret === undefined) {
218
+ isSecret = dbRec.isSecret;
240
219
  }
220
+ return dbRec;
241
221
  }
242
- catch (err) {
243
- const errMsg = err?.message || String(err) || '';
244
- if (errMsg.includes('UNIQUE constraint failed')) {
245
- console.warn(`Detected UNIQUE constraint failed error when saving persistent var, reloading and retrying: ${name}`);
222
+ async function reactToValueChanged(value) {
223
+ if (name === "colorModePreference")
224
+ console.log(`colorModePreferences pvar value set: ${value}`);
225
+ // Skip if the observable has already moved on to a different value (handles rapid updates)
226
+ // This prevents stale writes that could cause infinite update loops between pvar instances
227
+ if (!(0, lodash_1.isEqual)(persistentVar(), value)) {
228
+ return;
229
+ }
230
+ if (!rec?.persistentVarId && value === defaultValue) {
231
+ return;
232
+ }
233
+ if (!rec?.persistentVarId) {
246
234
  rec = await loadRecFromDb();
247
- persistentVar(rec.value.value);
248
235
  }
249
- else {
250
- console.error('Error saving persistent var', { name, value, rec, err });
251
- throw err;
236
+ if ((0, lodash_1.isEqual)(value, rec.value.value)) {
237
+ return;
238
+ }
239
+ rec.value.value = value;
240
+ const dc = getDataContext();
241
+ const table = PersistentVars(dc);
242
+ try {
243
+ rec = await table.save(rec);
244
+ if (name === "colorModePreference") {
245
+ console.log(`Saved var ${name} to db:`, rec.value.value);
246
+ }
247
+ }
248
+ catch (err) {
249
+ const errMsg = err?.message || String(err) || "";
250
+ if (errMsg.includes("UNIQUE constraint failed")) {
251
+ console.warn(`Detected UNIQUE constraint failed error when saving persistent var, reloading and retrying: ${name}`);
252
+ rec = await loadRecFromDb();
253
+ persistentVar(rec.value.value);
254
+ }
255
+ else {
256
+ console.error("Error saving persistent var", { name, value, rec, err });
257
+ throw err;
258
+ }
252
259
  }
253
260
  }
254
- }
255
- deleteVarImpl = async () => {
256
- const dc = getDataContext();
257
- const table = PersistentVars(dc);
258
- if (rec?.persistentVarId) {
259
- await table.delete(rec);
260
- rec = undefined;
261
- }
262
- if (defaultValue !== undefined) {
263
- persistentVar(defaultValue);
264
- }
265
- };
266
- // subscribe to db changes
267
- userContext.subscribeToDataChangedAcrossAllGroups(exports.persistentVarsMetaData.name, async (evt) => {
268
- const dbRec = evt.data.dataObject;
269
- const dbName = getVarNameInDb();
270
- if (!rec?.persistentVarId && dbRec.name === dbName) {
271
- rec = dbRec;
272
- }
273
- if (dbRec.persistentVarId === rec?.persistentVarId) {
274
- if (evt.data.op === 'delete') {
261
+ deleteVarImpl = async () => {
262
+ const dc = getDataContext();
263
+ const table = PersistentVars(dc);
264
+ if (rec?.persistentVarId) {
265
+ await table.delete(rec);
275
266
  rec = undefined;
276
- if (defaultValue !== undefined) {
277
- persistentVar(defaultValue);
278
- }
279
267
  }
280
- else {
268
+ if (defaultValue !== undefined) {
269
+ persistentVar(defaultValue);
270
+ }
271
+ };
272
+ // subscribe to db changes
273
+ userContext.subscribeToDataChangedAcrossAllGroups(exports.persistentVarsMetaData.name, async (evt) => {
274
+ const dbRec = evt.data.dataObject;
275
+ const dbName = getVarNameInDb();
276
+ if (!rec?.persistentVarId && dbRec.name === dbName) {
281
277
  rec = dbRec;
282
- if (!(0, lodash_1.isEqual)(persistentVar(), rec.value.value)) {
283
- persistentVar(rec.value.value);
278
+ }
279
+ if (dbRec.persistentVarId === rec?.persistentVarId) {
280
+ if (evt.data.op === "delete") {
281
+ rec = undefined;
282
+ if (defaultValue !== undefined) {
283
+ persistentVar(defaultValue);
284
+ }
285
+ }
286
+ else {
287
+ rec = dbRec;
288
+ if (!(0, lodash_1.isEqual)(persistentVar(), rec.value.value)) {
289
+ persistentVar(rec.value.value);
290
+ }
284
291
  }
285
292
  }
293
+ });
294
+ // update group-dependent variables if group context changes and it hasn't been pinned to a specific data context
295
+ const groupDependentScopes = [
296
+ "group",
297
+ "groupDevice",
298
+ "groupUser",
299
+ ];
300
+ if (!opts?.dataContext && groupDependentScopes.includes(scope)) {
301
+ userContext.defaultDataContext.subscribe(async () => {
302
+ rec = await loadRecFromDb();
303
+ persistentVar(rec.value.value);
304
+ });
286
305
  }
287
- });
288
- // update group-dependent variables if group context changes and it hasn't been pinned to a specific data context
289
- const groupDependentScopes = ['group', 'groupDevice', 'groupUser'];
290
- if (!opts?.dataContext && groupDependentScopes.includes(scope)) {
291
- userContext.defaultDataContext.subscribe(async () => {
306
+ if (!setWithDbValue) {
292
307
  rec = await loadRecFromDb();
293
- persistentVar(rec.value.value);
294
- });
295
- }
296
- if (!setWithDbValue) {
297
- rec = await loadRecFromDb();
298
- if (!(0, lodash_1.isEqual)(rec.value.value, persistentVar())) {
299
- if (name === 'colorModePreference') {
300
- console.log(`Loaded persistent var ${name} from db:`, rec.value.value);
308
+ if (!(0, lodash_1.isEqual)(rec.value.value, persistentVar())) {
309
+ if (name === "colorModePreference") {
310
+ console.log(`Loaded persistent var ${name} from db:`, rec.value.value);
311
+ }
312
+ persistentVar(rec.value.value);
301
313
  }
302
- persistentVar(rec.value.value);
303
314
  }
304
- }
305
- persistentVar.subscribe(newValue => {
306
- persistentVar.loadingPromise = persistentVar.loadingPromise.then(async () => {
307
- await reactToValueChanged(newValue);
308
- return persistentVar;
315
+ persistentVar.subscribe((newValue) => {
316
+ persistentVar.loadingPromise = persistentVar.loadingPromise.then(async () => {
317
+ await reactToValueChanged(newValue);
318
+ return persistentVar;
319
+ });
309
320
  });
310
- });
311
- }
312
- catch (err) {
313
- console.error(`an unexpected occurred while loading a persistent var: ${name}`, err);
314
- }
315
- resolve(persistentVar);
321
+ }
322
+ catch (err) {
323
+ console.error(`an unexpected occurred while loading a persistent var: ${name}`, err);
324
+ }
325
+ resolve(persistentVar);
326
+ })();
316
327
  });
317
328
  return persistentVar;
318
329
  }
@@ -1,5 +1,5 @@
1
- import { z } from 'zod';
2
- import type { DataContext } from '../context/data-context';
1
+ import { z } from "zod";
2
+ import type { DataContext } from "../context/data-context";
3
3
  export declare const tableDefinitionRecordSchema: z.ZodObject<{
4
4
  tableId: z.ZodString;
5
5
  name: z.ZodString;
@@ -7,25 +7,25 @@ export declare const tableDefinitionRecordSchema: z.ZodObject<{
7
7
  versionNumber: z.ZodDefault<z.ZodNumber>;
8
8
  }, "strip", z.ZodTypeAny, {
9
9
  name: string;
10
- tableId: string;
11
10
  metaData: {} & {
12
11
  [k: string]: any;
13
12
  };
13
+ tableId: string;
14
14
  versionNumber: number;
15
15
  }, {
16
16
  name: string;
17
- tableId: string;
18
17
  metaData: {} & {
19
18
  [k: string]: any;
20
19
  };
20
+ tableId: string;
21
21
  versionNumber?: number | undefined;
22
22
  }>;
23
23
  export type ITableDefinitionRecord = z.infer<typeof tableDefinitionRecordSchema>;
24
24
  export declare function TableDefinitions(dataContext?: DataContext): import("./orm").Table<{
25
25
  name: string;
26
- tableId: string;
27
26
  metaData: {} & {
28
27
  [k: string]: any;
29
28
  };
29
+ tableId: string;
30
30
  versionNumber: number;
31
31
  }>;
@@ -3,24 +3,25 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.tableDefinitionRecordSchema = void 0;
4
4
  exports.TableDefinitions = TableDefinitions;
5
5
  const zod_1 = require("zod");
6
- const types_1 = require("./orm/types");
7
6
  const user_context_singleton_1 = require("../context/user-context-singleton");
8
- const table_definitions_system_1 = require("./orm/table-definitions.system");
9
7
  const zod_types_1 = require("../types/zod-types");
8
+ const table_definitions_system_1 = require("./orm/table-definitions.system");
9
+ const types_1 = require("./orm/types");
10
10
  exports.tableDefinitionRecordSchema = zod_1.z.object({
11
- tableId: zod_1.z.string().describe('Primary key - same as ITableMetaData.tableId'),
12
- name: zod_1.z.string().describe('Table name'),
13
- metaData: zod_types_1.zodAnyObject.describe('Full ITableMetaData object serialized as JSON'),
14
- versionNumber: zod_1.z.number().default(0).describe('Version number set by the developer in the table definition; higher value wins during sync'),
11
+ tableId: zod_1.z.string().describe("Primary key - same as ITableMetaData.tableId"),
12
+ name: zod_1.z.string().describe("Table name"),
13
+ metaData: zod_types_1.zodAnyObject.describe("Full ITableMetaData object serialized as JSON"),
14
+ versionNumber: zod_1.z
15
+ .number()
16
+ .default(0)
17
+ .describe("Version number set by the developer in the table definition; higher value wins during sync"),
15
18
  });
16
19
  const metaData = {
17
- name: 'TableDefinitions',
18
- description: 'Stores table schemas as tracked data so peers can learn about table definitions without needing the full package installed',
19
- primaryKeyName: 'tableId',
20
+ name: "TableDefinitions",
21
+ description: "Stores table schemas as tracked data so peers can learn about table definitions without needing the full package installed",
22
+ primaryKeyName: "tableId",
20
23
  fields: (0, types_1.schemaToFields)(exports.tableDefinitionRecordSchema),
21
- indexes: [
22
- { fields: ['name'] },
23
- ],
24
+ indexes: [{ fields: ["name"] }],
24
25
  };
25
26
  (0, table_definitions_system_1.registerSystemTableDefinition)(metaData, exports.tableDefinitionRecordSchema);
26
27
  function TableDefinitions(dataContext) {
@@ -3,23 +3,23 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.toolTestSchema = void 0;
4
4
  exports.ToolTests = ToolTests;
5
5
  const zod_1 = require("zod");
6
- const zod_types_1 = require("../types/zod-types");
7
- const types_1 = require("./orm/types");
8
6
  const user_context_singleton_1 = require("../context/user-context-singleton");
7
+ const zod_types_1 = require("../types/zod-types");
9
8
  const table_definitions_system_1 = require("./orm/table-definitions.system");
9
+ const types_1 = require("./orm/types");
10
10
  exports.toolTestSchema = zod_1.z.object({
11
11
  toolTestId: zod_types_1.zodPeerId,
12
12
  toolId: zod_types_1.zodPeerId,
13
13
  description: zod_1.z.string(),
14
- code: zod_1.z.string().default(''),
14
+ code: zod_1.z.string().default(""),
15
15
  input: zod_1.z.any(),
16
16
  output: zod_1.z.any(),
17
17
  mocks: zod_1.z.any().optional(),
18
18
  });
19
19
  const metaData = {
20
- name: 'ToolTests',
21
- description: 'Tests for tools',
22
- primaryKeyName: 'toolTestId',
20
+ name: "ToolTests",
21
+ description: "Tests for tools",
22
+ primaryKeyName: "toolTestId",
23
23
  fields: (0, types_1.schemaToFields)(exports.toolTestSchema),
24
24
  };
25
25
  (0, table_definitions_system_1.registerSystemTableDefinition)(metaData, exports.toolTestSchema);
@@ -3,11 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.toolSchema = exports.ioSchema = exports.IOSchemaType = void 0;
4
4
  exports.Tools = Tools;
5
5
  const zod_1 = require("zod");
6
+ const user_context_singleton_1 = require("../context/user-context-singleton");
6
7
  const field_type_1 = require("../types/field-type");
7
8
  const zod_types_1 = require("../types/zod-types");
8
- const types_1 = require("./orm/types");
9
- const user_context_singleton_1 = require("../context/user-context-singleton");
10
9
  const table_definitions_system_1 = require("./orm/table-definitions.system");
10
+ const types_1 = require("./orm/types");
11
11
  var IOSchemaType;
12
12
  (function (IOSchemaType) {
13
13
  IOSchemaType["none"] = "none";
@@ -21,27 +21,37 @@ exports.ioSchema = zod_1.z.object({
21
21
  });
22
22
  exports.toolSchema = zod_1.z.object({
23
23
  toolId: zod_types_1.zodPeerId,
24
- name: zod_1.z.string().describe('The name of the tool'),
25
- usageDescription: zod_1.z.string().describe('A description of the what the tool does and how to use it. This is used by the AI to reason about the tool at runtime and in the middle of performing tasks.'),
26
- detailedDescription: zod_1.z.string().optional().describe('A full description of the tool which may include examples, references, screenshots, etc. This is intended for humans and AI to decide if this is a tool they want to include in their toolbox while preparing to work on tasks.'),
27
- inputSchema: exports.ioSchema.describe('The input schema of the tool'),
28
- outputSchema: exports.ioSchema.describe('The output schema of the tool'),
29
- configSchema: exports.ioSchema.optional().describe('The schema of any configuration values that the tool may need'),
30
- code: zod_1.z.string().default('').describe('The code that implements the tool'),
31
- codeRepository: zod_1.z.string().optional().describe('The repository where the code for the tool is stored'),
24
+ name: zod_1.z.string().describe("The name of the tool"),
25
+ usageDescription: zod_1.z
26
+ .string()
27
+ .describe("A description of the what the tool does and how to use it. This is used by the AI to reason about the tool at runtime and in the middle of performing tasks."),
28
+ detailedDescription: zod_1.z
29
+ .string()
30
+ .optional()
31
+ .describe("A full description of the tool which may include examples, references, screenshots, etc. This is intended for humans and AI to decide if this is a tool they want to include in their toolbox while preparing to work on tasks."),
32
+ inputSchema: exports.ioSchema.describe("The input schema of the tool"),
33
+ outputSchema: exports.ioSchema.describe("The output schema of the tool"),
34
+ configSchema: exports.ioSchema
35
+ .optional()
36
+ .describe("The schema of any configuration values that the tool may need"),
37
+ code: zod_1.z.string().default("").describe("The code that implements the tool"),
38
+ codeRepository: zod_1.z
39
+ .string()
40
+ .optional()
41
+ .describe("The repository where the code for the tool is stored"),
32
42
  // TODO versioning somehow, maybe a git tag or branch
33
- isAssistantRunner: zod_1.z.boolean().optional().describe('Whether this tool is a model that can be used to run an assistant'),
43
+ isAssistantRunner: zod_1.z
44
+ .boolean()
45
+ .optional()
46
+ .describe("Whether this tool is a model that can be used to run an assistant"),
34
47
  });
35
48
  const metaData = {
36
- name: 'Tools',
37
- description: 'Tools that can be used by assistants.',
38
- primaryKeyName: 'toolId',
49
+ name: "Tools",
50
+ description: "Tools that can be used by assistants.",
51
+ primaryKeyName: "toolId",
39
52
  fields: (0, types_1.schemaToFields)(exports.toolSchema),
40
- iconClassName: 'bi bi-tools',
41
- indexes: [
42
- { fields: ['name'], },
43
- { fields: ['isAssistantRunner'], },
44
- ],
53
+ iconClassName: "bi bi-tools",
54
+ indexes: [{ fields: ["name"] }, { fields: ["isAssistantRunner"] }],
45
55
  };
46
56
  (0, table_definitions_system_1.registerSystemTableDefinition)(metaData, exports.toolSchema);
47
57
  function Tools(dataContext) {
@@ -1,4 +1,4 @@
1
- import type { IUser } from './users';
1
+ import type { IUser } from "./users";
2
2
  /**
3
3
  * Signs a user object with the provided secret key
4
4
  * @param user The user object to sign
@@ -22,25 +22,25 @@ function verifyUserSignature(user, oldUser) {
22
22
  if (!user.signature) {
23
23
  // Allow unsigned stubs only when no signed record already exists
24
24
  if (oldUser?.signature) {
25
- throw new Error('Cannot overwrite a signed user record with an unsigned one');
25
+ throw new Error("Cannot overwrite a signed user record with an unsigned one");
26
26
  }
27
27
  return;
28
28
  }
29
29
  (0, keys_1.verifyObjectSignature)(user);
30
- const signerPublicKey = (0, keys_1.getPublicKeyFromObjectSignature)(user) ?? '';
30
+ const signerPublicKey = (0, keys_1.getPublicKeyFromObjectSignature)(user) ?? "";
31
31
  // New user: signature must match their own public key
32
32
  if (!oldUser) {
33
33
  if (signerPublicKey !== user.publicKey) {
34
- throw new Error('User signature must be signed with their own public key');
34
+ throw new Error("User signature must be signed with their own public key");
35
35
  }
36
36
  return;
37
37
  }
38
38
  // Existing user: signature must match existing public key
39
39
  if (signerPublicKey !== oldUser.publicKey) {
40
- throw new Error('User update must be signed by the user themselves');
40
+ throw new Error("User update must be signed by the user themselves");
41
41
  }
42
42
  // Prevent public key changes (for now)
43
43
  if (user.publicKey !== oldUser.publicKey) {
44
- throw new Error('Public key changes are not currently supported');
44
+ throw new Error("Public key changes are not currently supported");
45
45
  }
46
46
  }