lowlander 0.2.2 → 0.2.4
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/README.md +92 -46
- package/build/client/client.d.ts +6 -7
- package/build/client/client.js +69 -9
- package/build/client/client.js.map +1 -1
- package/build/examples/helloworld/server/api.d.ts +13 -0
- package/build/examples/helloworld/server/api.d.ts.map +1 -1
- package/build/examples/helloworld/server/api.js +27 -2
- package/build/examples/helloworld/server/api.js.map +1 -1
- package/build/server/protocol.js +1 -1
- package/build/server/protocol.js.map +1 -1
- package/build/server/server.d.ts +10 -4
- package/build/server/server.d.ts.map +1 -1
- package/build/server/server.js +8 -4
- package/build/server/server.js.map +1 -1
- package/build/server/wshandler.d.ts.map +1 -1
- package/build/server/wshandler.js +2 -1
- package/build/server/wshandler.js.map +1 -1
- package/build/tsconfig.client.tsbuildinfo +1 -1
- package/build/tsconfig.server.tsbuildinfo +1 -1
- package/client/client.ts +84 -16
- package/package.json +5 -4
- package/server/protocol.ts +1 -1
- package/server/server.ts +9 -4
- package/server/wshandler.ts +2 -1
- package/skill/Connection.md +35 -0
- package/skill/Connection_pruneCommitIds.md +8 -0
- package/skill/SKILL.md +53 -186
- package/skill/ServerProxy.md +30 -0
- package/skill/Socket.md +22 -0
- package/skill/Socket_send.md +11 -0
- package/skill/Socket_subscribe.md +8 -0
- package/skill/createStreamType.md +45 -0
- package/skill/pushModel.md +14 -0
- package/skill/sendModel.md +14 -0
- package/skill/start.md +21 -0
- package/skill/warpsocket.md +3 -0
package/skill/SKILL.md
CHANGED
|
@@ -134,6 +134,24 @@ export function streamPerson(name: string) {
|
|
|
134
134
|
|
|
135
135
|
On the client, this returns a reactive Aberdeen proxy that updates live when server data changes.
|
|
136
136
|
|
|
137
|
+
```ts
|
|
138
|
+
// Client-side
|
|
139
|
+
const person = api.streamPerson('Alice');
|
|
140
|
+
// person.value starts as undefined while loading, and
|
|
141
|
+
// then becomes a live-updating reactive proxy object of Alice's data
|
|
142
|
+
A.dump(person);
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Lowlander will keep `person.value` up-to-date as long as the Aberdeen scope containing `api.streamPerson` remains active. When the scope is destroyed, the stream subscription is automatically cancelled.
|
|
146
|
+
|
|
147
|
+
It's quite common for the same RPC call to be used to get the same stream multiple times in a short period; when navigating back and forth, or when navigating to a new page that requires some of the same data as the previous page. To optimize for this, `createStreamType` accepts an optional `cache` parameter (in seconds).
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
const PersonStream = createStreamType(Person, fields, { cache: 30 }); // cache for 30s after going out of scope
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
After a stream with caching goes out of scope, the server keeps it alive for that many seconds, so that if the same stream is requested again with the same parameters, it can be reused instantly without re-sending initial data or re-subscribing to updates. Cached stream rpcs also deduplicate within that time window, so if the same stream is requested multiple times while it's still active or cached, only one stream is created on the server and shared among all requests.
|
|
154
|
+
|
|
137
155
|
### ServerProxy for Stateful APIs
|
|
138
156
|
|
|
139
157
|
Wrap a class instance to expose per-connection stateful methods:
|
|
@@ -285,90 +303,29 @@ Set `EDINBURGH_LOG_LEVEL` similarly for Edinburgh internals.
|
|
|
285
303
|
|
|
286
304
|
The following is auto-generated from `server/server.ts`:
|
|
287
305
|
|
|
288
|
-
### createStreamType · function
|
|
306
|
+
### [createStreamType](createStreamType.md) · function
|
|
289
307
|
|
|
290
308
|
Creates a stream type for reactive model streaming to clients with automatic updates.
|
|
291
309
|
|
|
292
|
-
|
|
293
|
-
Supports nested linked models and type-safe field selection.
|
|
294
|
-
|
|
295
|
-
**Signature:** `<T, S extends FieldSelection<T>>(Model: typeof E.Model<unknown> & (new (...args: any[]) => T), selection: S & ValidateSelection<T, S>) => typeof StreamType`
|
|
296
|
-
|
|
297
|
-
**Type Parameters:**
|
|
298
|
-
|
|
299
|
-
- `T`
|
|
300
|
-
- `S extends FieldSelection<T>`
|
|
301
|
-
|
|
302
|
-
**Parameters:**
|
|
303
|
-
|
|
304
|
-
- `Model: ModelClass & (new (...args: any[]) => T)` - - The Edinburgh model class
|
|
305
|
-
- `selection: S & ValidateSelection<T, S>` - - Field selection: `true` for simple fields, nested object for linked models
|
|
306
|
-
|
|
307
|
-
**Returns:** Stream type class to instantiate in API functions
|
|
308
|
-
|
|
309
|
-
**Examples:**
|
|
310
|
-
|
|
311
|
-
```ts
|
|
312
|
-
|
|
313
|
-
### sendModel · function
|
|
310
|
+
### [sendModel](sendModel.md) · function
|
|
314
311
|
|
|
315
312
|
Sends (updated) data for `model` to `target`.
|
|
316
313
|
`target` is a virtual socket with a requestId+'d' user prefix, or a channel that subscribes such virtual sockets.
|
|
317
314
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
**Parameters:**
|
|
321
|
-
|
|
322
|
-
- `target: Uint8Array | number | number[]`
|
|
323
|
-
- `model: E.Model<any>`
|
|
324
|
-
- `commitId: number`
|
|
325
|
-
- `StreamType: typeof StreamTypeBase<any>`
|
|
326
|
-
- `changed?: E.Change`
|
|
327
|
-
|
|
328
|
-
### pushModel · function
|
|
315
|
+
### [pushModel](pushModel.md) · function
|
|
329
316
|
|
|
330
317
|
Subscribes `target` to this model, and sends initial data.
|
|
331
318
|
`target` is a virtual socket with a requestId+'d' user prefix, or a channel that subscribes such virtual sockets.
|
|
332
319
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
**Parameters:**
|
|
336
|
-
|
|
337
|
-
- `target: number | Uint8Array | number[]`
|
|
338
|
-
- `model: E.Model<any>`
|
|
339
|
-
- `commitId: number`
|
|
340
|
-
- `SubStreamType: typeof StreamTypeBase<any>`
|
|
341
|
-
- `delta: number`
|
|
342
|
-
|
|
343
|
-
### start · function
|
|
320
|
+
### [start](start.md) · function
|
|
344
321
|
|
|
345
322
|
Starts the Lowlander WebSocket server.
|
|
346
323
|
|
|
347
|
-
**Signature:** `(mainApiFile: string, opts?: { bind?: string; threads?: number; injectWarpSocket?: typeof import("/var/home/frank/projects/lowlander/node_modules/warpsocket/dist/src/index", { with: { "resolution-mode": "import" } }); }) => Promise<void>`
|
|
348
|
-
|
|
349
|
-
**Parameters:**
|
|
350
|
-
|
|
351
|
-
- `mainApiFile: string` - - Absolute path to the compiled API file exporting server functions
|
|
352
|
-
- `opts: {bind?: string, threads?: number, injectWarpSocket?: typeof realWarpsocket}` (optional)
|
|
353
|
-
|
|
354
|
-
**Examples:**
|
|
355
|
-
|
|
356
|
-
```ts
|
|
357
|
-
import { start } from 'lowlander/server';
|
|
358
|
-
import { fileURLToPath } from 'url';
|
|
359
|
-
import { resolve, dirname } from 'path';
|
|
360
|
-
|
|
361
|
-
const API_FILE = resolve(dirname(fileURLToPath(import.meta.url)), 'api.js');
|
|
362
|
-
start(API_FILE, { bind: '0.0.0.0:8080' });
|
|
363
|
-
```
|
|
364
|
-
|
|
365
324
|
### logLevel · constant
|
|
366
325
|
|
|
367
326
|
**Value:** `number`
|
|
368
327
|
|
|
369
|
-
### warpsocket · class
|
|
370
|
-
|
|
371
|
-
**Type:** `typeof import("/var/home/frank/projects/lowlander/node_modules/warpsocket/dist/src/index", { with: { "resolution-mode": "import" } })`
|
|
328
|
+
### [warpsocket](warpsocket.md) · class
|
|
372
329
|
|
|
373
330
|
### StreamTypeBase · abstract class
|
|
374
331
|
|
|
@@ -386,118 +343,55 @@ start(API_FILE, { bind: '0.0.0.0:8080' });
|
|
|
386
343
|
|
|
387
344
|
**Type:** `number`
|
|
388
345
|
|
|
389
|
-
####
|
|
346
|
+
#### StreamTypeBase.cache · static property
|
|
390
347
|
|
|
391
|
-
**
|
|
348
|
+
**Type:** `number`
|
|
392
349
|
|
|
393
|
-
|
|
350
|
+
#### streamTypeBase.toString · method
|
|
394
351
|
|
|
352
|
+
**Signature:** `() => string`
|
|
395
353
|
|
|
396
|
-
### ServerProxy · class
|
|
354
|
+
### [ServerProxy](ServerProxy.md) · class
|
|
397
355
|
|
|
398
356
|
Wraps a server-side API object to create a stateful, type-safe proxy accessible from clients.
|
|
399
357
|
Use for authentication, sessions, or any stateful context that persists across RPC calls.
|
|
400
358
|
|
|
401
|
-
**Type Parameters:**
|
|
402
|
-
|
|
403
|
-
- `API extends object`
|
|
404
|
-
- `RETURN`
|
|
405
|
-
|
|
406
|
-
**Examples:**
|
|
407
|
-
|
|
408
|
-
```ts
|
|
409
|
-
export class UserAPI {
|
|
410
|
-
constructor(public user: User) {}
|
|
411
|
-
getSecret() { return this.user.secret; }
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
export async function authenticate(token: string) {
|
|
415
|
-
const user = await validateToken(token);
|
|
416
|
-
return new ServerProxy(new UserAPI(user), user.name);
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
// Client: auth.value is user name, auth.serverProxy.getSecret() calls UserAPI method
|
|
420
|
-
```
|
|
421
|
-
|
|
422
|
-
**Constructor Parameters:**
|
|
423
|
-
|
|
424
|
-
- `api`: - Server-side API object exposed to the client
|
|
425
|
-
- `value`: - Value returned immediately to the client
|
|
426
|
-
|
|
427
359
|
#### serverProxy.toString · method
|
|
428
360
|
|
|
429
361
|
**Signature:** `() => string`
|
|
430
362
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
### Socket · class
|
|
363
|
+
### [Socket](Socket.md) · class
|
|
435
364
|
|
|
436
365
|
Server-side socket for pushing data to a client. Server functions with `Socket<T>` parameters
|
|
437
366
|
receive client callbacks on the client side.
|
|
438
367
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
- `T`
|
|
442
|
-
|
|
443
|
-
**Examples:**
|
|
444
|
-
|
|
445
|
-
```ts
|
|
446
|
-
// Server
|
|
447
|
-
export function streamNumbers(socket: Socket<number>) {
|
|
448
|
-
setInterval(() => {
|
|
449
|
-
if (!socket.send(Math.random())) clearInterval(interval);
|
|
450
|
-
}, 1000);
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
// Client
|
|
454
|
-
api.streamNumbers(num => console.log(num));
|
|
455
|
-
```
|
|
456
|
-
|
|
457
|
-
#### socket.send · method
|
|
368
|
+
#### [socket.send](Socket_send.md) · method
|
|
458
369
|
|
|
459
370
|
Sends data to the client.
|
|
460
371
|
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
**Parameters:**
|
|
464
|
-
|
|
465
|
-
- `data: T` - - Data to send (automatically serialized)
|
|
466
|
-
|
|
467
|
-
**Returns:** `true` if sent, `false` if socket is closed
|
|
468
|
-
|
|
469
|
-
#### socket.subscribe · method
|
|
470
|
-
|
|
471
|
-
**Signature:** `(channel: Uint8Array<ArrayBufferLike>, delta?: number) => void`
|
|
472
|
-
|
|
473
|
-
**Parameters:**
|
|
474
|
-
|
|
475
|
-
- `channel: Uint8Array`
|
|
476
|
-
- `delta: any` (optional)
|
|
372
|
+
#### [socket.subscribe](Socket_subscribe.md) · method
|
|
477
373
|
|
|
478
374
|
#### socket.toString · method
|
|
479
375
|
|
|
480
376
|
**Signature:** `() => string`
|
|
481
377
|
|
|
482
|
-
**Parameters:**
|
|
483
|
-
|
|
484
|
-
|
|
485
378
|
#### socket.[Symbol.for('nodejs.util.inspect.custom')] · method
|
|
486
379
|
|
|
487
380
|
**Signature:** `() => string`
|
|
488
381
|
|
|
489
|
-
**Parameters:**
|
|
490
|
-
|
|
491
|
-
|
|
492
382
|
## Client API Reference
|
|
493
383
|
|
|
494
384
|
The following is auto-generated from `client/client.ts`:
|
|
495
385
|
|
|
496
|
-
###
|
|
386
|
+
### setLogLevel · function
|
|
497
387
|
|
|
498
|
-
Set to
|
|
388
|
+
Set to 0-3 for increasing verbosity.
|
|
499
389
|
|
|
500
|
-
**
|
|
390
|
+
**Signature:** `(level: number) => void`
|
|
391
|
+
|
|
392
|
+
**Parameters:**
|
|
393
|
+
|
|
394
|
+
- `level: number`
|
|
501
395
|
|
|
502
396
|
### ClientProxyObject · type
|
|
503
397
|
|
|
@@ -507,42 +401,11 @@ Transforms server-side API objects to client-side proxy objects with type-safe R
|
|
|
507
401
|
[K in keyof T]: ClientProxyFunction<T[K]>
|
|
508
402
|
}`
|
|
509
403
|
|
|
510
|
-
### Connection · class
|
|
404
|
+
### [Connection](Connection.md) · class
|
|
511
405
|
|
|
512
406
|
WebSocket connection to a Lowlander server with type-safe RPC, automatic reconnection,
|
|
513
407
|
and reactive updates.
|
|
514
408
|
|
|
515
|
-
**Type Parameters:**
|
|
516
|
-
|
|
517
|
-
- `T`
|
|
518
|
-
|
|
519
|
-
**Examples:**
|
|
520
|
-
|
|
521
|
-
```ts
|
|
522
|
-
import type * as API from './server/api.js';
|
|
523
|
-
const conn = new Connection<typeof API>('ws://localhost:8080/');
|
|
524
|
-
|
|
525
|
-
// Simple RPC - returns PromiseProxy
|
|
526
|
-
const sum = conn.api.add(1, 2);
|
|
527
|
-
|
|
528
|
-
// Server proxy for stateful APIs
|
|
529
|
-
const auth = conn.api.authenticate('token');
|
|
530
|
-
const secret = auth.serverProxy.getSecret();
|
|
531
|
-
|
|
532
|
-
// Streaming with callbacks
|
|
533
|
-
conn.api.streamData(data => console.log(data));
|
|
534
|
-
|
|
535
|
-
// Use within Aberdeen reactive scopes
|
|
536
|
-
$(() => {
|
|
537
|
-
dump(conn.isOnline());
|
|
538
|
-
dump(sum);
|
|
539
|
-
});
|
|
540
|
-
```
|
|
541
|
-
|
|
542
|
-
**Constructor Parameters:**
|
|
543
|
-
|
|
544
|
-
- `url`: - WebSocket URL (e.g., 'ws://localhost:8080/'), or a fake WebSocket object for testing
|
|
545
|
-
|
|
546
409
|
#### connection.ws · property
|
|
547
410
|
|
|
548
411
|
**Type:** `WebSocket`
|
|
@@ -563,6 +426,10 @@ $(() => {
|
|
|
563
426
|
|
|
564
427
|
**Type:** `ValueRef<boolean>`
|
|
565
428
|
|
|
429
|
+
#### connection.streamCache · property
|
|
430
|
+
|
|
431
|
+
**Type:** `Map<string, StreamCacheEntry>`
|
|
432
|
+
|
|
566
433
|
#### connection.api · property
|
|
567
434
|
|
|
568
435
|
Type-safe proxy to the server-side API. Methods return `PromiseProxy` objects
|
|
@@ -577,29 +444,29 @@ Returns the current connection status. Reactive in Aberdeen scopes.
|
|
|
577
444
|
|
|
578
445
|
**Signature:** `() => boolean`
|
|
579
446
|
|
|
580
|
-
**Parameters:**
|
|
581
|
-
|
|
582
|
-
|
|
583
447
|
#### connection.connect · method
|
|
584
448
|
|
|
585
449
|
**Signature:** `() => void`
|
|
586
450
|
|
|
587
|
-
**Parameters:**
|
|
588
|
-
|
|
589
|
-
|
|
590
451
|
#### connection.reconnect · method
|
|
591
452
|
|
|
592
453
|
**Signature:** `() => void`
|
|
593
454
|
|
|
455
|
+
#### [connection.pruneCommitIds](Connection_pruneCommitIds.md) · method
|
|
456
|
+
|
|
457
|
+
#### connection.cancelRequest · method
|
|
458
|
+
|
|
459
|
+
**Signature:** `(request: ActiveRequest) => void`
|
|
460
|
+
|
|
594
461
|
**Parameters:**
|
|
595
462
|
|
|
463
|
+
- `request: ActiveRequest`
|
|
596
464
|
|
|
597
|
-
#### connection.
|
|
465
|
+
#### connection.startLinger · method
|
|
598
466
|
|
|
599
|
-
**Signature:** `(
|
|
467
|
+
**Signature:** `(cached: StreamCacheEntry) => void`
|
|
600
468
|
|
|
601
469
|
**Parameters:**
|
|
602
470
|
|
|
603
|
-
- `
|
|
604
|
-
- `maxCommitId: number`
|
|
471
|
+
- `cached: StreamCacheEntry`
|
|
605
472
|
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
### ServerProxy · class
|
|
2
|
+
|
|
3
|
+
Wraps a server-side API object to create a stateful, type-safe proxy accessible from clients.
|
|
4
|
+
Use for authentication, sessions, or any stateful context that persists across RPC calls.
|
|
5
|
+
|
|
6
|
+
**Type Parameters:**
|
|
7
|
+
|
|
8
|
+
- `API extends object`
|
|
9
|
+
- `RETURN`
|
|
10
|
+
|
|
11
|
+
**Examples:**
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
export class UserAPI {
|
|
15
|
+
constructor(public user: User) {}
|
|
16
|
+
getSecret() { return this.user.secret; }
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export async function authenticate(token: string) {
|
|
20
|
+
const user = await validateToken(token);
|
|
21
|
+
return new ServerProxy(new UserAPI(user), user.name);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Client: auth.value is user name, auth.serverProxy.getSecret() calls UserAPI method
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**Constructor Parameters:**
|
|
28
|
+
|
|
29
|
+
- `api`: - Server-side API object exposed to the client
|
|
30
|
+
- `value`: - Value returned immediately to the client
|
package/skill/Socket.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
### Socket · class
|
|
2
|
+
|
|
3
|
+
Server-side socket for pushing data to a client. Server functions with `Socket<T>` parameters
|
|
4
|
+
receive client callbacks on the client side.
|
|
5
|
+
|
|
6
|
+
**Type Parameters:**
|
|
7
|
+
|
|
8
|
+
- `T`
|
|
9
|
+
|
|
10
|
+
**Examples:**
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
// Server
|
|
14
|
+
export function streamNumbers(socket: Socket<number>) {
|
|
15
|
+
setInterval(() => {
|
|
16
|
+
if (!socket.send(Math.random())) clearInterval(interval);
|
|
17
|
+
}, 1000);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Client
|
|
21
|
+
api.streamNumbers(num => console.log(num));
|
|
22
|
+
```
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
### createStreamType · function
|
|
2
|
+
|
|
3
|
+
Creates a stream type for reactive model streaming to clients with automatic updates.
|
|
4
|
+
|
|
5
|
+
Specify which fields to include; when they change, updates are pushed to subscribed clients.
|
|
6
|
+
Supports nested linked models and type-safe field selection.
|
|
7
|
+
|
|
8
|
+
**Signature:** `<T, S extends FieldSelection<T>>(Model: typeof E.Model<unknown> & (new (...args: any[]) => T), selection: S & ValidateSelection<T, S>, options?: { cache?: number; }) => typeof StreamType`
|
|
9
|
+
|
|
10
|
+
**Type Parameters:**
|
|
11
|
+
|
|
12
|
+
- `T`
|
|
13
|
+
- `S extends FieldSelection<T>`
|
|
14
|
+
|
|
15
|
+
**Parameters:**
|
|
16
|
+
|
|
17
|
+
- `Model: ModelClass & (new (...args: any[]) => T)` - - The Edinburgh model class
|
|
18
|
+
- `selection: S & ValidateSelection<T, S>` - - Field selection: `true` for simple fields, nested object for linked models
|
|
19
|
+
- `options?: { cache?: number }` - - Optional settings
|
|
20
|
+
|
|
21
|
+
**Returns:** Stream type class to instantiate in API functions
|
|
22
|
+
|
|
23
|
+
**Examples:**
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
@E.registerModel
|
|
27
|
+
class Person extends Model {
|
|
28
|
+
name = field(string);
|
|
29
|
+
age = field(number);
|
|
30
|
+
password = field(string);
|
|
31
|
+
friends = field(array(link(Person)));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Exclude password, include friends' names; cache 30s
|
|
35
|
+
const PersonStream = createStreamType(Person, {
|
|
36
|
+
name: true,
|
|
37
|
+
age: true,
|
|
38
|
+
friends: { name: true }
|
|
39
|
+
}, { cache: 30 });
|
|
40
|
+
|
|
41
|
+
export function streamPerson() {
|
|
42
|
+
const person = Person.byName.get('Alice')!;
|
|
43
|
+
return new PersonStream(person);
|
|
44
|
+
}
|
|
45
|
+
```
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
### pushModel · function
|
|
2
|
+
|
|
3
|
+
Subscribes `target` to this model, and sends initial data.
|
|
4
|
+
`target` is a virtual socket with a requestId+'d' user prefix, or a channel that subscribes such virtual sockets.
|
|
5
|
+
|
|
6
|
+
**Signature:** `(target: number | Uint8Array<ArrayBufferLike> | number[], model: Model<any>, commitId: number, SubStreamType: typeof StreamTypeBase<any>, delta: number) => void`
|
|
7
|
+
|
|
8
|
+
**Parameters:**
|
|
9
|
+
|
|
10
|
+
- `target: number | Uint8Array | number[]`
|
|
11
|
+
- `model: E.Model<any>`
|
|
12
|
+
- `commitId: number`
|
|
13
|
+
- `SubStreamType: typeof StreamTypeBase<any>`
|
|
14
|
+
- `delta: number`
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
### sendModel · function
|
|
2
|
+
|
|
3
|
+
Sends (updated) data for `model` to `target`.
|
|
4
|
+
`target` is a virtual socket with a requestId+'d' user prefix, or a channel that subscribes such virtual sockets.
|
|
5
|
+
|
|
6
|
+
**Signature:** `(target: number | Uint8Array<ArrayBufferLike> | number[], model: Model<any>, commitId: number, StreamType: typeof StreamTypeBase<any>, changed?: Change) => void`
|
|
7
|
+
|
|
8
|
+
**Parameters:**
|
|
9
|
+
|
|
10
|
+
- `target: Uint8Array | number | number[]`
|
|
11
|
+
- `model: E.Model<any>`
|
|
12
|
+
- `commitId: number`
|
|
13
|
+
- `StreamType: typeof StreamTypeBase<any>`
|
|
14
|
+
- `changed?: E.Change`
|
package/skill/start.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
### start · function
|
|
2
|
+
|
|
3
|
+
Starts the Lowlander WebSocket server.
|
|
4
|
+
|
|
5
|
+
**Signature:** `(mainApiFile: string, opts?: { bind?: string; threads?: number; injectWarpSocket?: typeof import("/var/home/frank/projects/warpsocket/dist/src/index", { with: { "resolution-mode": "import" } }); }) => Promise<void>`
|
|
6
|
+
|
|
7
|
+
**Parameters:**
|
|
8
|
+
|
|
9
|
+
- `mainApiFile: string` - - Absolute path to the compiled API file exporting server functions
|
|
10
|
+
- `opts: {bind?: string, threads?: number, injectWarpSocket?: typeof realWarpsocket}` (optional)
|
|
11
|
+
|
|
12
|
+
**Examples:**
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
import { start } from 'lowlander/server';
|
|
16
|
+
import { fileURLToPath } from 'url';
|
|
17
|
+
import { resolve, dirname } from 'path';
|
|
18
|
+
|
|
19
|
+
const API_FILE = resolve(dirname(fileURLToPath(import.meta.url)), 'api.js');
|
|
20
|
+
start(API_FILE, { bind: '0.0.0.0:8080' });
|
|
21
|
+
```
|