@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.
- package/BlobPolyfill.js +1 -1
- package/BlobPolyfill.js.map +1 -1
- package/README.md +493 -26
- package/bots/BotCalculations.js +9 -17
- package/bots/BotCalculations.js.map +1 -1
- package/bots/BotEvents.d.ts +146 -3
- package/bots/BotEvents.js +19 -4
- package/bots/BotEvents.js.map +1 -1
- package/common/ConnectionInfo.d.ts +1 -9
- package/common/DenialReason.d.ts +1 -1
- package/common/PolicyPermissions.d.ts +866 -754
- package/common/PolicyPermissions.js +53 -0
- package/common/PolicyPermissions.js.map +1 -1
- package/common/RemoteActions.d.ts +33 -299
- package/common/Version.d.ts +35 -1
- package/common/Version.js +50 -2
- package/common/Version.js.map +1 -1
- package/common/WebConfig.d.ts +163 -69
- package/common/WebConfig.js +86 -23
- package/common/WebConfig.js.map +1 -1
- package/common/WebManifest.d.ts +27 -0
- package/common/WebManifest.js +110 -0
- package/common/WebManifest.js.map +1 -0
- package/documents/RemoteYjsSharedDocument.js +3 -5
- package/documents/RemoteYjsSharedDocument.js.map +1 -1
- package/documents/YjsSharedDocument.js +5 -10
- package/documents/YjsSharedDocument.js.map +1 -1
- package/forms/FormError.js +1 -2
- package/forms/FormError.js.map +1 -1
- package/http/GenericHttpInterface.d.ts +11 -20
- package/http/GenericHttpInterface.js.map +1 -1
- package/math/Rotation.js +3 -4
- package/math/Rotation.js.map +1 -1
- package/package.json +77 -78
- package/partitions/AuxPartitionConfig.d.ts +11 -1
- package/partitions/AuxPartitionFactories.js +3 -0
- package/partitions/AuxPartitionFactories.js.map +1 -1
- package/partitions/MemoryPartition.js +5 -7
- package/partitions/MemoryPartition.js.map +1 -1
- package/partitions/OtherPlayersPartition.js +4 -8
- package/partitions/OtherPlayersPartition.js.map +1 -1
- package/partitions/PartitionAuthSource.js +2 -4
- package/partitions/PartitionAuthSource.js.map +1 -1
- package/partitions/PartitionUtils.d.ts +12 -0
- package/partitions/PartitionUtils.js +65 -6
- package/partitions/PartitionUtils.js.map +1 -1
- package/partitions/RemoteYjsPartition.d.ts +1 -0
- package/partitions/RemoteYjsPartition.js +39 -6
- package/partitions/RemoteYjsPartition.js.map +1 -1
- package/partitions/YjsPartition.d.ts +2 -1
- package/partitions/YjsPartition.js +46 -28
- package/partitions/YjsPartition.js.map +1 -1
- package/records/AccountBalance.d.ts +82 -0
- package/records/AccountBalance.js +63 -0
- package/records/AccountBalance.js.map +1 -0
- package/records/AuthUtils.js +7 -7
- package/records/AuthUtils.js.map +1 -1
- package/records/RecordKeys.js +2 -3
- package/records/RecordKeys.js.map +1 -1
- package/records/index.d.ts +1 -0
- package/records/index.js +1 -0
- package/records/index.js.map +1 -1
- package/rpc/ErrorCodes.d.ts +1 -1
- package/rpc/ErrorCodes.js +3 -3
- package/rpc/ErrorCodes.js.map +1 -1
- package/rpc/GenericRPCInterface.d.ts +56 -13
- package/rpc/GenericRPCInterface.js +87 -55
- package/rpc/GenericRPCInterface.js.map +1 -1
- package/rpc/Result.d.ts +4 -1
- package/rpc/Result.js +21 -13
- package/rpc/Result.js.map +1 -1
- package/utils.d.ts +1 -1
- package/utils.js +6 -4
- package/utils.js.map +1 -1
- package/websockets/InstRecordsClient.js +6 -7
- package/websockets/InstRecordsClient.js.map +1 -1
- package/websockets/Utils.js +3 -3
- package/websockets/Utils.js.map +1 -1
- package/websockets/WebsocketEvents.d.ts +246 -997
- package/websockets/WebsocketEvents.js +3 -3
- package/websockets/WebsocketEvents.js.map +1 -1
- package/yjs/YjsHelpers.d.ts +9 -0
- package/yjs/YjsHelpers.js +28 -1
- package/yjs/YjsHelpers.js.map +1 -1
- package/yjs/YjsIndexedDBPersistence.js +2 -3
- 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
|
|
25
|
+
this.type = options?.type;
|
|
26
26
|
}
|
|
27
27
|
async arrayBuffer() {
|
|
28
28
|
let bytes = [];
|
package/BlobPolyfill.js.map
CHANGED
|
@@ -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,
|
|
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
|
-
#
|
|
1
|
+
# @casual-simulation/aux-common
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@casual-simulation/aux-common)
|
|
4
4
|
|
|
5
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
342
|
+
const bot1 = createBot('test1', {
|
|
25
343
|
quantity: 10,
|
|
26
344
|
});
|
|
27
|
-
const
|
|
345
|
+
const bot2 = createBot('test2', {
|
|
28
346
|
quantity: 5,
|
|
29
347
|
});
|
|
30
|
-
const
|
|
348
|
+
const bot3 = createBot('test3', {
|
|
31
349
|
quantity: 5,
|
|
32
350
|
});
|
|
33
351
|
|
|
34
|
-
const context = createCalculationContext([
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
81
|
-
|
|
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
|
package/bots/BotCalculations.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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(
|
|
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 =
|
|
2880
|
+
const name = script ?? formula ?? tag;
|
|
2889
2881
|
return {
|
|
2890
2882
|
name,
|
|
2891
2883
|
isScript: !!script,
|