@casual-simulation/aux-common 3.8.2-alpha.19511653187 → 3.10.3-alpha.20787554310

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 (86) hide show
  1. package/BlobPolyfill.js +1 -1
  2. package/BlobPolyfill.js.map +1 -1
  3. package/README.md +493 -26
  4. package/bots/BotCalculations.js +9 -17
  5. package/bots/BotCalculations.js.map +1 -1
  6. package/bots/BotEvents.d.ts +146 -3
  7. package/bots/BotEvents.js +19 -4
  8. package/bots/BotEvents.js.map +1 -1
  9. package/common/ConnectionInfo.d.ts +1 -9
  10. package/common/DenialReason.d.ts +1 -1
  11. package/common/PolicyPermissions.d.ts +866 -754
  12. package/common/PolicyPermissions.js +53 -0
  13. package/common/PolicyPermissions.js.map +1 -1
  14. package/common/RemoteActions.d.ts +33 -299
  15. package/common/Version.d.ts +35 -1
  16. package/common/Version.js +50 -2
  17. package/common/Version.js.map +1 -1
  18. package/common/WebConfig.d.ts +163 -69
  19. package/common/WebConfig.js +86 -23
  20. package/common/WebConfig.js.map +1 -1
  21. package/common/WebManifest.d.ts +27 -0
  22. package/common/WebManifest.js +110 -0
  23. package/common/WebManifest.js.map +1 -0
  24. package/documents/RemoteYjsSharedDocument.js +3 -5
  25. package/documents/RemoteYjsSharedDocument.js.map +1 -1
  26. package/documents/YjsSharedDocument.js +5 -10
  27. package/documents/YjsSharedDocument.js.map +1 -1
  28. package/forms/FormError.js +1 -2
  29. package/forms/FormError.js.map +1 -1
  30. package/http/GenericHttpInterface.d.ts +11 -20
  31. package/http/GenericHttpInterface.js.map +1 -1
  32. package/math/Rotation.js +3 -4
  33. package/math/Rotation.js.map +1 -1
  34. package/package.json +77 -78
  35. package/partitions/AuxPartitionConfig.d.ts +11 -1
  36. package/partitions/AuxPartitionFactories.js +3 -0
  37. package/partitions/AuxPartitionFactories.js.map +1 -1
  38. package/partitions/MemoryPartition.js +5 -7
  39. package/partitions/MemoryPartition.js.map +1 -1
  40. package/partitions/OtherPlayersPartition.js +4 -8
  41. package/partitions/OtherPlayersPartition.js.map +1 -1
  42. package/partitions/PartitionAuthSource.js +2 -4
  43. package/partitions/PartitionAuthSource.js.map +1 -1
  44. package/partitions/PartitionUtils.d.ts +12 -0
  45. package/partitions/PartitionUtils.js +65 -6
  46. package/partitions/PartitionUtils.js.map +1 -1
  47. package/partitions/RemoteYjsPartition.d.ts +1 -0
  48. package/partitions/RemoteYjsPartition.js +39 -6
  49. package/partitions/RemoteYjsPartition.js.map +1 -1
  50. package/partitions/YjsPartition.d.ts +2 -1
  51. package/partitions/YjsPartition.js +46 -28
  52. package/partitions/YjsPartition.js.map +1 -1
  53. package/records/AccountBalance.d.ts +82 -0
  54. package/records/AccountBalance.js +63 -0
  55. package/records/AccountBalance.js.map +1 -0
  56. package/records/AuthUtils.js +7 -7
  57. package/records/AuthUtils.js.map +1 -1
  58. package/records/RecordKeys.js +2 -3
  59. package/records/RecordKeys.js.map +1 -1
  60. package/records/index.d.ts +1 -0
  61. package/records/index.js +1 -0
  62. package/records/index.js.map +1 -1
  63. package/rpc/ErrorCodes.d.ts +1 -1
  64. package/rpc/ErrorCodes.js +3 -3
  65. package/rpc/ErrorCodes.js.map +1 -1
  66. package/rpc/GenericRPCInterface.d.ts +56 -13
  67. package/rpc/GenericRPCInterface.js +87 -55
  68. package/rpc/GenericRPCInterface.js.map +1 -1
  69. package/rpc/Result.d.ts +4 -1
  70. package/rpc/Result.js +21 -13
  71. package/rpc/Result.js.map +1 -1
  72. package/utils.d.ts +1 -1
  73. package/utils.js +6 -4
  74. package/utils.js.map +1 -1
  75. package/websockets/InstRecordsClient.js +6 -7
  76. package/websockets/InstRecordsClient.js.map +1 -1
  77. package/websockets/Utils.js +3 -3
  78. package/websockets/Utils.js.map +1 -1
  79. package/websockets/WebsocketEvents.d.ts +246 -997
  80. package/websockets/WebsocketEvents.js +3 -3
  81. package/websockets/WebsocketEvents.js.map +1 -1
  82. package/yjs/YjsHelpers.d.ts +9 -0
  83. package/yjs/YjsHelpers.js +28 -1
  84. package/yjs/YjsHelpers.js.map +1 -1
  85. package/yjs/YjsIndexedDBPersistence.js +2 -3
  86. package/yjs/YjsIndexedDBPersistence.js.map +1 -1
package/BlobPolyfill.js CHANGED
@@ -22,7 +22,7 @@ if (!globalThis.Blob) {
22
22
  globalThis.Blob = class {
23
23
  constructor(parts, options) {
24
24
  this.parts = parts.slice();
25
- this.type = options === null || options === void 0 ? void 0 : options.type;
25
+ this.type = options?.type;
26
26
  }
27
27
  async arrayBuffer() {
28
28
  let bytes = [];
@@ -1 +1 @@
1
- {"version":3,"file":"BlobPolyfill.js","sourceRoot":"","sources":["BlobPolyfill.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;IACnB,IAAI,OAAO,OAAO,KAAK,WAAW,EAAE,CAAC;QACjC,OAAO,CAAC,IAAI,CACR,mFAAmF,CACtF,CAAC;IACN,CAAC;IACK,UAAW,CAAC,IAAI,GAAG;QAIrB,YAAY,KAAY,EAAE,OAAY;YAClC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;YAC3B,IAAI,CAAC,IAAI,GAAG,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,IAAI,CAAC;QAC9B,CAAC;QAED,KAAK,CAAC,WAAW;YACb,IAAI,KAAK,GAAG,EAAc,CAAC;YAC3B,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;YAClC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBAC5B,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAC3B,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;oBACrC,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC;gBAC3B,CAAC;qBAAM,IAAI,IAAI,YAAY,WAAW,EAAE,CAAC;oBACrC,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;gBACxC,CAAC;qBAAM,IAAI,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;oBAClC,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;gBAC/C,CAAC;qBAAM,IAAI,IAAI,YAAY,IAAI,EAAE,CAAC;oBAC9B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;oBACxC,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;gBAC1C,CAAC;YACL,CAAC;YAED,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;YACnC,OAAO,IAAI,CAAC,MAAM,CAAC;QACvB,CAAC;KACJ,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"BlobPolyfill.js","sourceRoot":"","sources":["BlobPolyfill.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;IACnB,IAAI,OAAO,OAAO,KAAK,WAAW,EAAE,CAAC;QACjC,OAAO,CAAC,IAAI,CACR,mFAAmF,CACtF,CAAC;IACN,CAAC;IACK,UAAW,CAAC,IAAI,GAAG;QAIrB,YAAY,KAAY,EAAE,OAAY;YAClC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;YAC3B,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,IAAI,CAAC;QAC9B,CAAC;QAED,KAAK,CAAC,WAAW;YACb,IAAI,KAAK,GAAG,EAAc,CAAC;YAC3B,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;YAClC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBAC5B,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAC3B,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;oBACrC,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC;gBAC3B,CAAC;qBAAM,IAAI,IAAI,YAAY,WAAW,EAAE,CAAC;oBACrC,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;gBACxC,CAAC;qBAAM,IAAI,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;oBAClC,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;gBAC/C,CAAC;qBAAM,IAAI,IAAI,YAAY,IAAI,EAAE,CAAC;oBAC9B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;oBACxC,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;gBAC1C,CAAC;YACL,CAAC;YAED,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;YACnC,OAAO,IAAI,CAAC,MAAM,CAAC;QACvB,CAAC;KACJ,CAAC;AACN,CAAC"}
package/README.md CHANGED
@@ -1,18 +1,336 @@
1
- # AUX Common
1
+ # @casual-simulation/aux-common
2
2
 
3
3
  [![npm (scoped)](https://img.shields.io/npm/v/@casual-simulation/aux-common.svg)](https://www.npmjs.com/package/@casual-simulation/aux-common)
4
4
 
5
- A library that contains common operations needed to modify and understand AUX files.
5
+ Core shared library for CasualOS (formerly AUX). This package provides foundational types, utilities, and infrastructure used across all CasualOS components.
6
+
7
+ ## Overview
8
+
9
+ `aux-common` is the foundation of the CasualOS platform, containing:
10
+
11
+ - **Bot System**: Core bot state management, calculations, actions, and events
12
+ - **Partitions**: Pluggable storage backends for bot state (memory, Yjs CRDT, remote sync)
13
+ - **WebSockets**: Real-time communication infrastructure for multi-user collaboration
14
+ - **RPC Framework**: Type-safe remote procedure calls with comprehensive error handling
15
+ - **Documents**: Collaborative document abstractions using Yjs CRDTs
16
+ - **Math Utilities**: Vector, quaternion, and rotation classes for 3D graphics
17
+ - **Common Types**: Actions, events, connections, permissions, and versioning
18
+ - **Records**: Data record management and WebPush notifications
19
+ - **Forms**: Form validation and error handling
20
+ - **State Machines**: State machine abstractions for complex workflows
21
+ - **Yjs Utilities**: Helper functions and IndexedDB persistence for CRDTs
6
22
 
7
23
  ## Installation
8
24
 
9
25
  ```bash
10
- $ npm install @casual-simulation/aux-common
26
+ npm install @casual-simulation/aux-common
27
+ ```
28
+
29
+ ## Package Structure
30
+
31
+ ```
32
+ aux-common/
33
+ ├── bots/ # Core bot system (RuntimeBot, actions, events, calculations)
34
+ ├── partitions/ # Storage backends (Memory, Yjs, Remote, OtherPlayers)
35
+ ├── websockets/ # WebSocket clients and inst records protocol
36
+ ├── common/ # Shared types (actions, connections, versioning)
37
+ ├── rpc/ # Type-safe RPC framework with error codes
38
+ ├── documents/ # Collaborative document abstractions (Yjs)
39
+ ├── math/ # Vector2/3, Quaternion, Rotation classes
40
+ ├── records/ # Data records and WebPush notifications
41
+ ├── yjs/ # Yjs helper functions and IndexedDB persistence
42
+ ├── http/ # HTTP interface types
43
+ ├── forms/ # Form validation and errors
44
+ ├── state-machine/ # State machine abstractions
45
+ ├── polyfill/ # Browser polyfills
46
+ ├── utils.ts # General utility functions
47
+ ├── Errors.ts # Error types and handling
48
+ ├── Event.ts # Event system
49
+ └── AppVersion.ts # Version management
50
+ ```
51
+
52
+ ## Core Modules
53
+
54
+ ### Bots (`bots/`)
55
+
56
+ The bot system is the heart of CasualOS, representing interactive objects with tags and behaviors.
57
+
58
+ **Key Exports**:
59
+
60
+ - `RuntimeBot`: Core bot interface with tags and state
61
+ - `BotActions`: Actions for creating, updating, and removing bots
62
+ - `BotCalculations`: Calculate bot properties (positions, rotations, colors)
63
+ - `BotEvents`: Event types (onClick, onCombine, onDrag, etc.)
64
+ - `BotIndex`: Fast lookup tables for bot queries
65
+ - `StateUpdatedEvent`: Bot state change events
66
+
67
+ **Example**:
68
+
69
+ ```typescript
70
+ import {
71
+ createBot,
72
+ botAdded,
73
+ calculateBotValue,
74
+ } from '@casual-simulation/aux-common';
75
+
76
+ const bot = createBot('player1', {
77
+ name: 'Alice',
78
+ position: { x: 0, y: 0, z: 0 },
79
+ color: '#ff0000',
80
+ });
81
+
82
+ const name = calculateBotValue(null, bot, 'name'); // "Alice"
83
+ ```
84
+
85
+ [See bots/README.md for detailed documentation](bots/README.md)
86
+
87
+ ### Partitions (`partitions/`)
88
+
89
+ Partitions provide pluggable storage backends for bot state, enabling different persistence and synchronization strategies.
90
+
91
+ **Key Exports**:
92
+
93
+ - `AuxPartition`: Base partition interface
94
+ - `MemoryPartition`: In-memory storage (fast, volatile)
95
+ - `YjsPartition`: Local Yjs CRDT with IndexedDB persistence
96
+ - `RemoteYjsPartition`: Networked Yjs with server synchronization
97
+ - `OtherPlayersPartition`: Multi-user player state aggregation
98
+ - `PartitionAuthSource`: Authentication coordination
99
+
100
+ **Example**:
101
+
102
+ ```typescript
103
+ import { createMemoryPartition } from '@casual-simulation/aux-common';
104
+
105
+ const partition = createMemoryPartition({
106
+ type: 'memory',
107
+ initialState: {},
108
+ });
109
+
110
+ partition.onBotsAdded.subscribe((bots) => {
111
+ console.log('Bots added:', bots);
112
+ });
113
+ ```
114
+
115
+ [See partitions/README.md for detailed documentation](partitions/README.md)
116
+
117
+ ### WebSockets (`websockets/`)
118
+
119
+ WebSocket infrastructure for real-time communication and inst records synchronization.
120
+
121
+ **Key Exports**:
122
+
123
+ - `ConnectionClient`: Base WebSocket client interface
124
+ - `AuthenticatedConnectionClient`: Authentication wrapper
125
+ - `InstRecordsClient`: Inst records protocol (branch watching, updates, device actions)
126
+ - `WebsocketEvents`: Complete protocol message types
127
+ - `MemoryConnectionClient`: In-memory client for testing
128
+
129
+ **Example**:
130
+
131
+ ```typescript
132
+ import { InstRecordsClient } from '@casual-simulation/aux-common';
133
+
134
+ const instClient = new InstRecordsClient(connectionClient);
135
+
136
+ const updates$ = instClient.watchBranchUpdates({
137
+ recordName: 'myRecord',
138
+ inst: 'myInst',
139
+ branch: 'main',
140
+ });
141
+
142
+ updates$.subscribe((event) => {
143
+ if (event.type === 'updates') {
144
+ console.log('Received updates:', event.updates);
145
+ }
146
+ });
147
+ ```
148
+
149
+ [See websockets/README.md for detailed documentation](websockets/README.md)
150
+
151
+ ### Common (`common/`)
152
+
153
+ Foundational types and utilities used throughout CasualOS.
154
+
155
+ **Key Exports**:
156
+
157
+ - `Action`: Base action type
158
+ - `RemoteActions`: Device actions and results
159
+ - `ConnectionInfo`: Connection metadata
160
+ - `ConnectionIndicator`: Connection tokens and credentials
161
+ - `CurrentVersion`: Version vectors for synchronization
162
+ - `StatusUpdate`: Progress and status messages
163
+ - `DenialReason`: Permission denial reasons
164
+
165
+ **Example**:
166
+
167
+ ```typescript
168
+ import type {
169
+ Action,
170
+ ConnectionInfo,
171
+ CurrentVersion,
172
+ } from '@casual-simulation/aux-common';
173
+
174
+ const action: Action = {
175
+ type: 'show_toast',
176
+ message: 'Hello, world!',
177
+ };
178
+ ```
179
+
180
+ [See common/README.md for detailed documentation](common/README.md)
181
+
182
+ ### RPC (`rpc/`)
183
+
184
+ Type-safe remote procedure call framework with comprehensive error handling.
185
+
186
+ **Key Exports**:
187
+
188
+ - `RPCResult`: Result types (success/error)
189
+ - `ErrorCodes`: 100+ standardized error codes
190
+ - `RPCError`: Error type with code and message
191
+ - Procedure types: `GetAccountInfoProcedure`, `CreateRecordProcedure`, etc.
192
+
193
+ **Example**:
194
+
195
+ ```typescript
196
+ import type { GetAccountInfoProcedure } from '@casual-simulation/aux-common';
197
+
198
+ const result = await client.call('getAccountInfo', {});
199
+
200
+ if (result.success) {
201
+ console.log('User:', result.data.user);
202
+ } else {
203
+ console.error('Error:', result.errorCode, result.errorMessage);
204
+ }
205
+ ```
206
+
207
+ ### Documents (`documents/`)
208
+
209
+ Collaborative document abstractions using Yjs CRDTs.
210
+
211
+ **Key Exports**:
212
+
213
+ - `YjsSharedDocument`: Local Yjs document with persistence
214
+ - `RemoteYjsSharedDocument`: Networked Yjs with server sync
215
+ - `SharedMap`, `SharedArray`, `SharedText`: Collaborative data structures
216
+
217
+ **Example**:
218
+
219
+ ```typescript
220
+ import { YjsSharedDocument } from '@casual-simulation/aux-common';
221
+
222
+ const doc = new YjsSharedDocument({
223
+ type: 'yjs',
224
+ branch: 'my-doc',
225
+ });
226
+
227
+ const map = doc.getMap('data');
228
+ map.set('key', 'value');
229
+ ```
230
+
231
+ [See documents/README.md for detailed documentation](documents/README.md)
232
+
233
+ ### Math (`math/`)
234
+
235
+ Vector, quaternion, and rotation classes for 3D graphics and spatial calculations.
236
+
237
+ **Key Exports**:
238
+
239
+ - `Vector2`: 2D vectors with arithmetic and geometric operations
240
+ - `Vector3`: 3D vectors with cross product and direction constants
241
+ - `Quaternion`: Quaternion representation of rotations
242
+ - `Rotation`: High-level rotation interface with multiple construction methods
243
+
244
+ **Example**:
245
+
246
+ ```typescript
247
+ import { Vector3, Rotation } from '@casual-simulation/aux-common';
248
+
249
+ const position = new Vector3(1, 2, 3);
250
+ const direction = position.normalize();
251
+
252
+ const rotation = new Rotation({
253
+ axis: new Vector3(0, 0, 1),
254
+ angle: Math.PI / 2,
255
+ });
11
256
  ```
12
257
 
13
- ## Usage
258
+ [See math/README.md for detailed documentation](math/README.md)
259
+
260
+ ### Yjs (`yjs/`)
261
+
262
+ Yjs utilities and IndexedDB persistence for CRDTs.
263
+
264
+ **Key Exports**:
265
+
266
+ - `YjsIndexedDBPersistence`: Local storage with automatic trimming
267
+ - `getStateVector`: Get version vector from Yjs document
268
+ - `createRelativePositionFromStateVector`: CRDT-safe positions
269
+ - `getTextChar`: Character-level text access
270
+
271
+ **Example**:
272
+
273
+ ```typescript
274
+ import {
275
+ YjsIndexedDBPersistence,
276
+ getStateVector,
277
+ } from '@casual-simulation/aux-common';
278
+ import * as Y from 'yjs';
279
+
280
+ const doc = new Y.Doc();
281
+ const persistence = new YjsIndexedDBPersistence('my-doc', doc);
282
+
283
+ await persistence.whenSynced;
284
+ console.log('Document loaded from IndexedDB');
285
+
286
+ const stateVector = getStateVector(doc);
287
+ console.log('State:', stateVector);
288
+ ```
289
+
290
+ [See yjs/README.md for detailed documentation](yjs/README.md)
291
+
292
+ ## Usage Examples
14
293
 
15
- #### Calculate a formula for some bots
294
+ ### Basic Bot Management
295
+
296
+ ```typescript
297
+ import {
298
+ createBot,
299
+ botAdded,
300
+ botUpdated,
301
+ createMemoryPartition,
302
+ } from '@casual-simulation/aux-common';
303
+
304
+ // Create partition
305
+ const partition = createMemoryPartition({
306
+ type: 'memory',
307
+ initialState: {},
308
+ });
309
+
310
+ // Add bot
311
+ await partition.applyEvents([
312
+ botAdded(
313
+ createBot('bot1', {
314
+ name: 'My Bot',
315
+ color: '#ff0000',
316
+ })
317
+ ),
318
+ ]);
319
+
320
+ // Update bot
321
+ await partition.applyEvents([
322
+ botUpdated('bot1', {
323
+ tags: { color: '#00ff00' },
324
+ }),
325
+ ]);
326
+
327
+ // Subscribe to changes
328
+ partition.onBotsUpdated.subscribe((updates) => {
329
+ console.log('Bots updated:', updates);
330
+ });
331
+ ```
332
+
333
+ ### Calculate Bot Formulas
16
334
 
17
335
  ```typescript
18
336
  import {
@@ -21,46 +339,36 @@ import {
21
339
  calculateFormulaValue,
22
340
  } from '@casual-simulation/aux-common';
23
341
 
24
- const file1 = createBot('test1', {
342
+ const bot1 = createBot('test1', {
25
343
  quantity: 10,
26
344
  });
27
- const file2 = createBot('test2', {
345
+ const bot2 = createBot('test2', {
28
346
  quantity: 5,
29
347
  });
30
- const file3 = createBot('test3', {
348
+ const bot3 = createBot('test3', {
31
349
  quantity: 5,
32
350
  });
33
351
 
34
- const context = createCalculationContext([file1, file2, file3]);
352
+ const context = createCalculationContext([bot1, bot2, bot3]);
35
353
 
36
354
  const formula = '=math.sum(getBotTagValues("#quantity"))';
37
355
  const result = calculateFormulaValue(context, formula);
38
356
 
39
- console.log(result);
40
-
41
- // Outputs:
42
- // 20
357
+ console.log(result); // 20
43
358
  ```
44
359
 
45
- #### Calculate events for an action script
360
+ ### Calculate Action Events
46
361
 
47
362
  ```typescript
48
363
  import {
49
364
  createBot,
50
- createCalculationContext,
51
365
  calculateFormulaEvents,
52
366
  } from '@casual-simulation/aux-common';
53
367
 
54
368
  const state = {
55
- test1: createBot('test1', {
56
- quantity: 10,
57
- }),
58
- test2: createBot('test2', {
59
- quantity: 5,
60
- }),
61
- test3: createBot('test3', {
62
- quantity: 5,
63
- }),
369
+ test1: createBot('test1', { quantity: 10 }),
370
+ test2: createBot('test2', { quantity: 5 }),
371
+ test3: createBot('test3', { quantity: 5 }),
64
372
  };
65
373
 
66
374
  const formula = `
@@ -76,7 +384,166 @@ for (let event of events) {
76
384
  }
77
385
  }
78
386
  }
387
+ // Outputs: [Toast] The total is 20
388
+ ```
79
389
 
80
- // Outputs:
81
- // [Toast] The total is 5
390
+ ### Real-Time Collaboration
391
+
392
+ ```typescript
393
+ import {
394
+ InstRecordsClient,
395
+ AuthenticatedConnectionClient,
396
+ createRemoteClientYjsPartition,
397
+ } from '@casual-simulation/aux-common';
398
+
399
+ // Set up connection
400
+ const authClient = new AuthenticatedConnectionClient(baseClient, authSource);
401
+ const instClient = new InstRecordsClient(authClient);
402
+
403
+ // Create remote partition
404
+ const partition = await createRemoteClientYjsPartition(
405
+ {
406
+ type: 'yjs_client',
407
+ client: instClient,
408
+ recordName: 'project',
409
+ inst: 'workspace',
410
+ branch: 'main',
411
+ },
412
+ authSource
413
+ );
414
+
415
+ partition.connect();
416
+
417
+ // Watch for updates
418
+ partition.onBotsAdded.subscribe((bots) => {
419
+ console.log('Bots added:', bots);
420
+ });
421
+ ```
422
+
423
+ ### 3D Calculations
424
+
425
+ ```typescript
426
+ import {
427
+ Vector3,
428
+ Rotation,
429
+ calculateBotValue,
430
+ } from '@casual-simulation/aux-common';
431
+
432
+ const bot = createBot('player', {
433
+ position: { x: 1, y: 2, z: 3 },
434
+ rotation: { x: 0, y: 0, z: Math.PI / 4 },
435
+ });
436
+
437
+ const position = calculateBotValue(null, bot, 'position') as Vector3;
438
+ const rotation = calculateBotValue(null, bot, 'rotation') as Rotation;
439
+
440
+ const forward = new Vector3(0, 1, 0);
441
+ const worldForward = rotation.rotateVector3(forward);
442
+
443
+ const newPosition = position.add(worldForward.multiplyScalar(5));
444
+ ```
445
+
446
+ ## Architecture
447
+
448
+ ```
449
+ ┌─────────────────────────────────────────────────────────────┐
450
+ │ CasualOS │
451
+ ├─────────────────────────────────────────────────────────────┤
452
+ │ │
453
+ │ ┌────────────────────────────────────────────────────┐ │
454
+ │ │ Application Layer │ │
455
+ │ │ (aux-vm, aux-runtime, aux-web, casualos-cli) │ │
456
+ │ └────────────────────┬───────────────────────────────┘ │
457
+ │ │ │
458
+ │ ┌────────────────────▼───────────────────────────────┐ │
459
+ │ │ @casual-simulation/aux-common │ │
460
+ │ ├────────────────────────────────────────────────────┤ │
461
+ │ │ │ │
462
+ │ │ ┌──────────┐ ┌───────────┐ ┌──────────────┐ │ │
463
+ │ │ │ Bots │ │Partitions │ │ WebSockets │ │ │
464
+ │ │ │ │ │ │ │ │ │ │
465
+ │ │ │ Actions │ │ Memory │ │ InstRecords │ │ │
466
+ │ │ │ Events │ │ Yjs │ │ Connection │ │ │
467
+ │ │ │ Calcs │ │ Remote │ │ Auth │ │ │
468
+ │ │ └──────────┘ └───────────┘ └──────────────┘ │ │
469
+ │ │ │ │
470
+ │ │ ┌──────────┐ ┌───────────┐ ┌──────────────┐ │ │
471
+ │ │ │ RPC │ │ Documents │ │ Math │ │ │
472
+ │ │ │ │ │ │ │ │ │ │
473
+ │ │ │ Errors │ │ SharedMap │ │ Vector2/3 │ │ │
474
+ │ │ │ Results │ │ SharedText│ │ Quaternion │ │ │
475
+ │ │ │ Procs │ │ Yjs CRDT │ │ Rotation │ │ │
476
+ │ │ └──────────┘ └───────────┘ └──────────────┘ │ │
477
+ │ │ │ │
478
+ │ │ ┌──────────┐ ┌───────────┐ ┌──────────────┐ │ │
479
+ │ │ │ Common │ │ Yjs │ │ Records │ │ │
480
+ │ │ │ │ │ │ │ │ │ │
481
+ │ │ │ Actions │ │ Helpers │ │ WebPush │ │ │
482
+ │ │ │ Connect │ │ IndexedDB │ │ Policies │ │ │
483
+ │ │ │ Versions │ │ Persist │ │ Schemas │ │ │
484
+ │ │ └──────────┘ └───────────┘ └──────────────┘ │ │
485
+ │ │ │ │
486
+ │ └────────────────────────────────────────────────────┘ │
487
+ │ │
488
+ └─────────────────────────────────────────────────────────────┘
82
489
  ```
490
+
491
+ ## Key Concepts
492
+
493
+ ### Bot-Centric Architecture
494
+
495
+ CasualOS uses a bot-centric model where everything is a bot with tags:
496
+
497
+ - **Bots**: Objects with ID and tags (key-value pairs)
498
+ - **Tags**: Properties that define bot behavior and appearance
499
+ - **Actions**: Events that modify bot state
500
+ - **Calculations**: Compute derived properties from tags
501
+
502
+ ### Partition-Based Storage
503
+
504
+ Storage is abstracted through partitions:
505
+
506
+ - **Memory**: Fast, volatile in-memory storage
507
+ - **Yjs**: Local CRDT with IndexedDB persistence
508
+ - **Remote**: Networked CRDT with server synchronization
509
+ - **OtherPlayers**: Multi-user player state aggregation
510
+
511
+ ### Real-Time Collaboration
512
+
513
+ Multi-user collaboration via:
514
+
515
+ - **Yjs CRDTs**: Conflict-free replicated data types
516
+ - **WebSocket Protocol**: Inst records protocol for updates
517
+ - **State Vectors**: Track document versions
518
+ - **Operational Transforms**: Apply edits at specific versions
519
+
520
+ ### Type-Safe Communication
521
+
522
+ Type safety across the stack:
523
+
524
+ - **RPC Framework**: Type-safe remote procedures
525
+ - **Zod Schemas**: Runtime validation
526
+ - **Error Codes**: Standardized error handling
527
+ - **Observable Streams**: RxJS for reactive programming
528
+
529
+ ## License
530
+
531
+ AGPL-3.0-only
532
+
533
+ ## Related Packages
534
+
535
+ - `@casual-simulation/aux-runtime`: Runtime execution engine
536
+ - `@casual-simulation/aux-vm`: Virtual machine implementations
537
+ - `@casual-simulation/aux-web`: Web application UI
538
+ - `@casual-simulation/aux-records`: Server-side record management
539
+ - `@casual-simulation/casualos-cli`: Command-line interface
540
+
541
+ ## Contributing
542
+
543
+ See [DEVELOPERS.md](../../DEVELOPERS.md) for development guidelines.
544
+
545
+ ## Version
546
+
547
+ Current version: 3.8.1
548
+
549
+ See [CHANGELOG.md](../../CHANGELOG.md) for version history
@@ -456,8 +456,7 @@ export function parseScript(value) {
456
456
  * @param value The value to parse.
457
457
  */
458
458
  export function parseScriptSafe(value) {
459
- var _a;
460
- return (_a = parseScript(value)) !== null && _a !== void 0 ? _a : value;
459
+ return parseScript(value) ?? value;
461
460
  }
462
461
  /**
463
462
  * Parses the given value into a module script.
@@ -478,8 +477,7 @@ export function parseModule(value) {
478
477
  * @param value The value to parse.
479
478
  */
480
479
  export function parseModuleSafe(value) {
481
- var _a;
482
- return (_a = parseModule(value)) !== null && _a !== void 0 ? _a : value;
480
+ return parseModule(value) ?? value;
483
481
  }
484
482
  /**
485
483
  * Parses the given value into a formula.
@@ -500,8 +498,7 @@ export function parseFormula(value) {
500
498
  * @param value The value to parse.
501
499
  */
502
500
  export function parseFormulaSafe(value) {
503
- var _a;
504
- return (_a = parseFormula(value)) !== null && _a !== void 0 ? _a : value;
501
+ return parseFormula(value) ?? value;
505
502
  }
506
503
  /**
507
504
  * Trims the leading script symbol off the given tag.
@@ -1550,9 +1547,8 @@ export function calculateAnchorPoint(value) {
1550
1547
  return DEFAULT_ANCHOR_POINT;
1551
1548
  }
1552
1549
  export function getMapPortalKind(bot) {
1553
- var _a;
1554
1550
  const kind = calculateStringTagValue(null, bot, 'auxMapPortalKind', null);
1555
- return (_a = calculateMapPortalKind(kind)) !== null && _a !== void 0 ? _a : DEFAULT_MAP_PORTAL_KIND;
1551
+ return calculateMapPortalKind(kind) ?? DEFAULT_MAP_PORTAL_KIND;
1556
1552
  }
1557
1553
  export function calculateMapPortalKind(value) {
1558
1554
  if (value === 'globe' || value === 'plane') {
@@ -1816,7 +1812,7 @@ function calculateBotCursor(calc, bot, tag) {
1816
1812
  y: position.y,
1817
1813
  };
1818
1814
  }
1819
- catch (_a) {
1815
+ catch {
1820
1816
  /* empty because we want to hide the error and return the default */
1821
1817
  }
1822
1818
  return DEFAULT_BOT_CURSOR;
@@ -2372,10 +2368,9 @@ export function simulationIdToString(id) {
2372
2368
  return id.channel;
2373
2369
  }
2374
2370
  export function parseSimulationId(id) {
2375
- var _a;
2376
2371
  try {
2377
2372
  let uri = new URL(id);
2378
- const channel = (_a = uri.searchParams.get('inst')) !== null && _a !== void 0 ? _a : uri.searchParams.get('server');
2373
+ const channel = uri.searchParams.get('inst') ?? uri.searchParams.get('server');
2379
2374
  if (channel) {
2380
2375
  return {
2381
2376
  success: true,
@@ -2827,9 +2822,8 @@ export function hasMaskForTag(bot, tag) {
2827
2822
  * @param space The space.
2828
2823
  */
2829
2824
  export function getTagValueForSpace(bot, tag, space) {
2830
- var _a, _b;
2831
2825
  if (hasValue(space)) {
2832
- return (_b = (_a = bot.masks) === null || _a === void 0 ? void 0 : _a[space]) === null || _b === void 0 ? void 0 : _b[tag];
2826
+ return bot.masks?.[space]?.[tag];
2833
2827
  }
2834
2828
  else {
2835
2829
  return bot.tags[tag];
@@ -2843,9 +2837,8 @@ export function getTagValueForSpace(bot, tag, space) {
2843
2837
  * @param tag The tag.
2844
2838
  */
2845
2839
  export function getSpaceForTag(bot, tag) {
2846
- var _a, _b;
2847
2840
  for (let space of TAG_MASK_SPACE_PRIORITIES) {
2848
- if (hasValue((_b = (_a = bot.masks) === null || _a === void 0 ? void 0 : _a[space]) === null || _b === void 0 ? void 0 : _b[tag])) {
2841
+ if (hasValue(bot.masks?.[space]?.[tag])) {
2849
2842
  return space;
2850
2843
  }
2851
2844
  }
@@ -2882,10 +2875,9 @@ export function getUpdateForTagAndSpace(tag, value, space) {
2882
2875
  * @param tag The tag to parse.
2883
2876
  */
2884
2877
  export function parseNewTag(tag) {
2885
- var _a;
2886
2878
  const script = parseScript(tag);
2887
2879
  const formula = parseFormula(tag);
2888
- const name = (_a = script !== null && script !== void 0 ? script : formula) !== null && _a !== void 0 ? _a : tag;
2880
+ const name = script ?? formula ?? tag;
2889
2881
  return {
2890
2882
  name,
2891
2883
  isScript: !!script,