lowlander 0.2.4 → 0.4.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.
- package/README.md +95 -51
- package/build/client/client.d.ts +8 -2
- package/build/client/client.js +10 -4
- package/build/client/client.js.map +1 -1
- package/build/examples/helloworld/server/api.d.ts +40 -23
- package/build/examples/helloworld/server/api.d.ts.map +1 -1
- package/build/examples/helloworld/server/api.js +59 -41
- package/build/examples/helloworld/server/api.js.map +1 -1
- package/build/server/protocol.d.ts +1 -0
- package/build/server/protocol.d.ts.map +1 -1
- package/build/server/protocol.js +1 -0
- package/build/server/protocol.js.map +1 -1
- package/build/server/server.d.ts +22 -22
- package/build/server/server.d.ts.map +1 -1
- package/build/server/server.js +15 -11
- package/build/server/server.js.map +1 -1
- package/build/server/wshandler.d.ts +1 -1
- package/build/server/wshandler.d.ts.map +1 -1
- package/build/server/wshandler.js +48 -8
- 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 +15 -8
- package/package.json +3 -3
- package/server/protocol.ts +1 -0
- package/server/server.ts +56 -36
- package/server/wshandler.ts +48 -9
- package/skill/SKILL.md +48 -8
- package/skill/ServerProxy.md +5 -0
- package/skill/createStreamType.md +9 -10
- package/skill/pushModel.md +1 -1
- package/skill/sendModel.md +1 -1
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
-
};
|
|
7
|
-
var Person_1, MyModel_1;
|
|
8
1
|
import * as E from "edinburgh";
|
|
9
2
|
import { ServerProxy, createStreamType } from "lowlander/server";
|
|
10
3
|
import * as warpsocket from "warpsocket";
|
|
@@ -20,7 +13,7 @@ export class UserAPI {
|
|
|
20
13
|
this.userName = userName;
|
|
21
14
|
}
|
|
22
15
|
get user() {
|
|
23
|
-
const result = Person.
|
|
16
|
+
const result = Person.get(this.userName);
|
|
24
17
|
if (!result)
|
|
25
18
|
throw new Error(`User '${this.userName}' not found`);
|
|
26
19
|
return result;
|
|
@@ -35,48 +28,63 @@ export class UserAPI {
|
|
|
35
28
|
return true;
|
|
36
29
|
}
|
|
37
30
|
}
|
|
38
|
-
const friend = Person.
|
|
31
|
+
const friend = Person.get(friendName);
|
|
39
32
|
if (!friend)
|
|
40
33
|
return false;
|
|
41
34
|
this.user.friends.push(friend);
|
|
42
35
|
return true;
|
|
43
36
|
}
|
|
37
|
+
onDrop() {
|
|
38
|
+
this.user.onlineCount--;
|
|
39
|
+
}
|
|
44
40
|
}
|
|
45
41
|
// Authentication example - returns a ServerProxy with both a value and API object
|
|
46
42
|
export async function authenticate(auth) {
|
|
47
|
-
|
|
48
|
-
const user = Person.byName.get(auth);
|
|
43
|
+
const user = Person.get(auth);
|
|
49
44
|
if (!user)
|
|
50
45
|
throw new Error('User not found');
|
|
46
|
+
user.onlineCount++;
|
|
51
47
|
// Client receives 'secret' as .value and UserAPI methods via .serverProxy
|
|
52
48
|
return new ServerProxy(new UserAPI(auth), 'secret');
|
|
53
49
|
}
|
|
50
|
+
export function getOnlineUsers() {
|
|
51
|
+
return [...Person.findBy('online')].map(p => p.name);
|
|
52
|
+
}
|
|
53
|
+
export function greet(name, greeting = 'Hello') {
|
|
54
|
+
return `${greeting}, ${name}!`;
|
|
55
|
+
}
|
|
54
56
|
// Edinburgh model definitions
|
|
55
|
-
|
|
56
|
-
static { Person_1 = this; }
|
|
57
|
-
static byName = E.primary(Person_1, 'name');
|
|
57
|
+
const Person = E.defineModel('Person', class {
|
|
58
58
|
name = E.field(E.string);
|
|
59
59
|
age = E.field(E.number);
|
|
60
|
-
friends = E.field(E.array(E.link(
|
|
60
|
+
friends = E.field(E.array(E.link(() => Person)));
|
|
61
61
|
password = E.field(E.string);
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
],
|
|
66
|
-
|
|
67
|
-
|
|
62
|
+
onlineCount = E.field(E.number);
|
|
63
|
+
}, {
|
|
64
|
+
pk: 'name',
|
|
65
|
+
index: { online: (p) => p.onlineCount > 0 ? [true] : [] },
|
|
66
|
+
});
|
|
67
|
+
const PersonStream = createStreamType(Person, { name: true, age: true });
|
|
68
|
+
export async function authenticateWithStream(auth) {
|
|
69
|
+
const user = Person.get(auth);
|
|
70
|
+
if (!user)
|
|
71
|
+
throw new Error('User not found');
|
|
72
|
+
user.onlineCount++;
|
|
73
|
+
// Client receives a live stream of {name, age} as .value, plus UserAPI via .serverProxy
|
|
74
|
+
return new ServerProxy(new UserAPI(auth), new PersonStream(user));
|
|
75
|
+
}
|
|
76
|
+
const MyModel = E.defineModel('MyModel', class {
|
|
68
77
|
id = E.field(E.identifier);
|
|
69
78
|
name = E.field(E.string);
|
|
70
|
-
next = E.field(E.opt(E.link(
|
|
79
|
+
next = E.field(E.opt(E.link(() => MyModel)));
|
|
71
80
|
owner = E.field(E.link(Person));
|
|
72
81
|
createdAt = E.field(E.dateTime);
|
|
73
82
|
meta = E.field(E.record(E.number));
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
], MyModel);
|
|
83
|
+
owners = E.field(E.record(E.link(() => Person)));
|
|
84
|
+
}, {
|
|
85
|
+
pk: 'id',
|
|
86
|
+
unique: { name: 'name' },
|
|
87
|
+
});
|
|
80
88
|
let ids;
|
|
81
89
|
export async function resetTestData(deleteEverything) {
|
|
82
90
|
if (deleteEverything) {
|
|
@@ -86,13 +94,16 @@ export async function resetTestData(deleteEverything) {
|
|
|
86
94
|
// in a new (nested) transaction, as deleteEverything will have done *its* work in separate transactions
|
|
87
95
|
// as well, and we need access to its results.
|
|
88
96
|
await E.transact(() => {
|
|
89
|
-
let p1 = Person.
|
|
90
|
-
let p2 = Person.
|
|
91
|
-
let p3 = Person.
|
|
97
|
+
let p1 = Person.get('Frank') || new Person({ name: 'Frank', age: 45, password: 'secret' });
|
|
98
|
+
let p2 = Person.get('Alice') || new Person({ name: 'Alice', age: 25, password: 'hidden', friends: [p1] });
|
|
99
|
+
let p3 = Person.get('Bob') || new Person({ name: 'Bob', age: 65, password: 'himom', friends: [p1, p2] });
|
|
92
100
|
if (p1.getState() === "created")
|
|
93
101
|
p1.friends = [p2, p3];
|
|
94
|
-
|
|
95
|
-
|
|
102
|
+
// Reset onlineCount on startup (no clients connected yet)
|
|
103
|
+
for (const p of [p1, p2, p3])
|
|
104
|
+
p.onlineCount = 0;
|
|
105
|
+
let m1 = MyModel.getBy('name', 'Test') || new MyModel({ name: 'Test', owner: p1, meta: { score: 42, level: 7 }, owners: { [p1.name]: p1, [p2.name]: p2 } });
|
|
106
|
+
let m2 = MyModel.getBy('name', 'Another') || new MyModel({ name: 'Another', owner: p2, next: m1, meta: {}, owners: {} });
|
|
96
107
|
ids = { p1: p1.name, p2: p2.name, m1: m1.id, m2: m2.id };
|
|
97
108
|
});
|
|
98
109
|
}
|
|
@@ -100,7 +111,7 @@ resetTestData(false);
|
|
|
100
111
|
``;
|
|
101
112
|
await E.transact(() => {
|
|
102
113
|
E.dump();
|
|
103
|
-
for (const p of Person.
|
|
114
|
+
for (const p of Person.find()) {
|
|
104
115
|
console.log('Person:', p.name, 'age', p.age, 'friends', p.friends.map(f => f.name).join(','), 'password', p.password);
|
|
105
116
|
}
|
|
106
117
|
});
|
|
@@ -123,35 +134,42 @@ const CachedStream = createStreamType(MyModel, {
|
|
|
123
134
|
name: true,
|
|
124
135
|
owner: { name: true },
|
|
125
136
|
}, { cache: 60 });
|
|
137
|
+
const LinkedRecordStream = createStreamType(MyModel, {
|
|
138
|
+
owners: { name: true },
|
|
139
|
+
});
|
|
126
140
|
// Example of model streaming - returns a reactive proxy that auto-updates on changes
|
|
127
141
|
export function streamModel() {
|
|
128
|
-
const m1 = MyModel.
|
|
142
|
+
const m1 = MyModel.get(ids.m1);
|
|
129
143
|
return new MyStream(m1);
|
|
130
144
|
}
|
|
131
145
|
export function streamModelCached() {
|
|
132
|
-
const m1 = MyModel.
|
|
146
|
+
const m1 = MyModel.get(ids.m1);
|
|
133
147
|
return new CachedStream(m1);
|
|
134
148
|
}
|
|
149
|
+
export function streamModelLinkedRecord() {
|
|
150
|
+
const m1 = MyModel.get(ids.m1);
|
|
151
|
+
return new LinkedRecordStream(m1);
|
|
152
|
+
}
|
|
135
153
|
export async function incrOwnerAge(delta) {
|
|
136
|
-
const m1 = MyModel.
|
|
154
|
+
const m1 = MyModel.get(ids.m1);
|
|
137
155
|
const current = m1.owner.age;
|
|
138
156
|
await new Promise(resolve => setTimeout(resolve, 50));
|
|
139
157
|
m1.owner.age = current + delta;
|
|
140
158
|
}
|
|
141
159
|
export function setOwnerAge(age) {
|
|
142
|
-
const m1 = MyModel.
|
|
160
|
+
const m1 = MyModel.get(ids.m1);
|
|
143
161
|
m1.owner.age = age;
|
|
144
162
|
}
|
|
145
163
|
export function setModelName(name) {
|
|
146
|
-
const m1 = MyModel.
|
|
164
|
+
const m1 = MyModel.get(ids.m1);
|
|
147
165
|
m1.name = name;
|
|
148
166
|
}
|
|
149
167
|
export function setMeta(key, value) {
|
|
150
|
-
const m1 = MyModel.
|
|
168
|
+
const m1 = MyModel.get(ids.m1);
|
|
151
169
|
m1.meta = { ...m1.meta, [key]: value };
|
|
152
170
|
}
|
|
153
171
|
export function deleteMeta(key) {
|
|
154
|
-
const m1 = MyModel.
|
|
172
|
+
const m1 = MyModel.get(ids.m1);
|
|
155
173
|
const copy = { ...m1.meta };
|
|
156
174
|
delete copy[key];
|
|
157
175
|
m1.meta = copy;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../../examples/helloworld/server/api.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../../examples/helloworld/server/api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,WAAW,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAU,MAAM,kBAAkB,CAAC;AACzE,OAAO,KAAK,UAAU,MAAM,YAAY,CAAC;AAEzC,MAAM,CAAC,MAAM,aAAa,GAAG,UAAU,CAAC,aAAa,CAAC;AAEtD,8BAA8B;AAC9B,MAAM,UAAU,GAAG,CAAC,CAAS,EAAE,CAAS;IACpC,OAAO,CAAC,GAAG,CAAC,CAAC;AACjB,CAAC;AAED,uEAAuE;AACvE,MAAM,OAAO,OAAO;IACG;IAAnB,YAAmB,QAAgB;QAAhB,aAAQ,GAAR,QAAQ,CAAQ;IAAG,CAAC;IAEvC,IAAI,IAAI;QACJ,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACzC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,SAAS,IAAI,CAAC,QAAQ,aAAa,CAAC,CAAC;QAClE,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,MAAM;QACF,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,sBAAsB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,aAAa,CAAC;IAC5G,CAAC;IAED,YAAY,CAAC,UAAkB;QAC3B,KAAI,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACxD,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBAC1B,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;gBACzC,OAAO,IAAI,CAAC;YAChB,CAAC;QACL,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACtC,IAAI,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAC1B,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/B,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,MAAM;QACF,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;IAC5B,CAAC;CACJ;AAED,kFAAkF;AAClF,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAY;IAC3C,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAC7C,IAAI,CAAC,WAAW,EAAE,CAAC;IACnB,0EAA0E;IAC1E,OAAO,IAAI,WAAW,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,cAAc;IAC1B,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,IAAY,EAAE,WAAmB,OAAO;IAC1D,OAAO,GAAG,QAAQ,KAAK,IAAI,GAAG,CAAC;AACnC,CAAC;AAGD,8BAA8B;AAC9B,MAAM,MAAM,GAAG,CAAC,CAAC,WAAW,CAAC,QAAQ,EAAE;IACnC,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACzB,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACxB,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACjD,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAC7B,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;CACnC,EAAE;IACC,EAAE,EAAE,MAAM;IACV,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE;CACjE,CAAC,CAAC;AAGH,MAAM,YAAY,GAAG,gBAAgB,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;AAEzE,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,IAAY;IACrD,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAC7C,IAAI,CAAC,WAAW,EAAE,CAAC;IACnB,wFAAwF;IACxF,OAAO,IAAI,WAAW,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;AACtE,CAAC;AAED,MAAM,OAAO,GAAG,CAAC,CAAC,WAAW,CAAC,SAAS,EAAE;IACrC,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IAC3B,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACzB,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC7C,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAChC,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAChC,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IACnC,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;CACpD,EAAE;IACC,EAAE,EAAE,IAAI;IACR,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;CAC3B,CAAC,CAAC;AAEH,IAAI,GAAqD,CAAC;AAC1D,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,gBAAyB;IACzD,IAAI,gBAAgB,EAAE,CAAC;QACnB,MAAM,CAAC,CAAC,gBAAgB,EAAE,CAAC;IAC/B,CAAC;IAED,iGAAiG;IACjG,wGAAwG;IACxG,8CAA8C;IAC9C,MAAM,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE;QAClB,IAAI,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,MAAM,CAAC,EAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAC,CAAC,CAAC;QACzF,IAAI,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,MAAM,CAAC,EAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAC,CAAC,CAAC;QACxG,IAAI,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,MAAM,CAAC,EAAC,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAC,CAAC,CAAC;QACvG,IAAI,EAAE,CAAC,QAAQ,EAAE,KAAK,SAAS;YAAE,EAAE,CAAC,OAAO,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QACvD,0DAA0D;QAC1D,KAAK,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;YAAE,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC;QAChD,IAAI,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,IAAI,OAAO,CAAC,EAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAC,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAC,EAAE,MAAM,EAAE,EAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,EAAC,EAAC,CAAC,CAAC;QACtJ,IAAI,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,IAAI,IAAI,OAAO,CAAC,EAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAC,CAAC,CAAC;QACvH,GAAG,GAAG,EAAC,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;AACP,CAAC;AACD,aAAa,CAAC,KAAK,CAAC,CAAC;AACrB,EAAE,CAAA;AACF,MAAM,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE;IAClB,CAAC,CAAC,IAAI,EAAE,CAAC;IACT,KAAI,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC1H,CAAC;AACL,CAAC,CAAC,CAAC;AAGH,sEAAsE;AACtE,qFAAqF;AACrF,MAAM,QAAQ,GAAG,gBAAgB,CAAC,OAAO,EAAE;IACvC,IAAI,EAAE,IAAI;IACV,SAAS,EAAE,IAAI;IACf,IAAI,EAAE,IAAI;IACV,KAAK,EAAE;QACH,IAAI,EAAE,IAAI;QACV,GAAG,EAAE,IAAI;QACT,OAAO,EAAE;YACL,IAAI,EAAE,IAAI;YACV,GAAG,EAAE,IAAI;SACZ;KACJ;CACJ,CAAC,CAAC;AAEH,MAAM,YAAY,GAAG,gBAAgB,CAAC,OAAO,EAAE;IAC3C,IAAI,EAAE,IAAI;IACV,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;CACxB,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;AAElB,MAAM,kBAAkB,GAAG,gBAAgB,CAAC,OAAO,EAAE;IACjD,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;CACzB,CAAC,CAAC;AAEH,qFAAqF;AACrF,MAAM,UAAU,WAAW;IACvB,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC;IAChC,OAAO,IAAI,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC7B,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC;IAChC,OAAO,IAAI,YAAY,CAAC,EAAE,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,uBAAuB;IACnC,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC;IAChC,OAAO,IAAI,kBAAkB,CAAC,EAAE,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,KAAa;IAC5C,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC;IAChC,MAAM,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC;IAC7B,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;IACtD,EAAE,CAAC,KAAK,CAAC,GAAG,GAAG,OAAO,GAAG,KAAK,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,GAAW;IACnC,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC;IAChC,EAAE,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAY;IACrC,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC;IAChC,EAAE,CAAC,IAAI,GAAG,IAAI,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,GAAW,EAAE,KAAa;IAC9C,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC;IAChC,EAAE,CAAC,IAAI,GAAG,EAAC,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAW;IAClC,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC;IAChC,MAAM,IAAI,GAAG,EAAC,GAAG,EAAE,CAAC,IAAI,EAAC,CAAC;IAC1B,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;IACjB,EAAE,CAAC,IAAI,GAAG,IAAI,CAAC;AACnB,CAAC;AAGD,uDAAuD;AACvD,0EAA0E;AAC1E,MAAM,UAAU,eAAe,CAAC,MAAsB;IAClD,IAAI,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE;QAC5B,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAC5B,sDAAsD;QACtD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;YAC9B,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;YAClC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC5B,CAAC;IACL,CAAC,EAAE,IAAI,CAAC,CAAC;AACb,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../server/protocol.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,eAAe
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../server/protocol.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,eAAe;;;;;;;CAO3B,CAAC;AAOF,eAAO,MAAM,eAAe;;;CAG3B,CAAC"}
|
package/build/server/protocol.js
CHANGED
|
@@ -6,6 +6,7 @@ export const SERVER_MESSAGES = {
|
|
|
6
6
|
response: 'r', // followed by result + virtualSocketIds
|
|
7
7
|
response_proxy: 'p', // followed by result + virtualSocketIds (like above, but indicate that a ServerProxy has been created for this request)
|
|
8
8
|
response_model: 'm', // followed by virtualSocketIds + dbKey + cacheMs (undefined = no caching/dedup)
|
|
9
|
+
response_proxy_model: 'q', // followed by virtualSocketIds + dbKey + cacheMs — like response_model but a ServerProxy was also registered
|
|
9
10
|
model_data: 'd', // followed by dbKey + commitId + delta
|
|
10
11
|
};
|
|
11
12
|
// The virtualSocketIds in a response or response_model is stored by the client and must
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../server/protocol.ts"],"names":[],"mappings":"AAAA,iDAAiD;AAEjD,KAAK;AAEL,kCAAkC;AAClC,MAAM,CAAC,MAAM,eAAe,GAAG;IAC3B,KAAK,EAAE,GAAG,EAAE,2BAA2B;IACvC,QAAQ,EAAE,GAAG,EAAE,wCAAwC;IACvD,cAAc,EAAE,GAAG,EAAE,wHAAwH;IAC7I,cAAc,EAAE,GAAG,EAAE,gFAAgF;IACrG,UAAU,EAAE,GAAG,EAAE,uCAAuC;CAC3D,CAAC;AAEF,wFAAwF;AACxF,2BAA2B;AAC3B,yHAAyH;AAEzH,kCAAkC;AAClC,MAAM,CAAC,MAAM,eAAe,GAAG;IAC3B,IAAI,EAAE,CAAC,EAAE,4DAA4D;IACrE,MAAM,EAAE,CAAC,EAAE,2DAA2D;CACzE,CAAC"}
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../server/protocol.ts"],"names":[],"mappings":"AAAA,iDAAiD;AAEjD,KAAK;AAEL,kCAAkC;AAClC,MAAM,CAAC,MAAM,eAAe,GAAG;IAC3B,KAAK,EAAE,GAAG,EAAE,2BAA2B;IACvC,QAAQ,EAAE,GAAG,EAAE,wCAAwC;IACvD,cAAc,EAAE,GAAG,EAAE,wHAAwH;IAC7I,cAAc,EAAE,GAAG,EAAE,gFAAgF;IACrG,oBAAoB,EAAE,GAAG,EAAE,6GAA6G;IACxI,UAAU,EAAE,GAAG,EAAE,uCAAuC;CAC3D,CAAC;AAEF,wFAAwF;AACxF,2BAA2B;AAC3B,yHAAyH;AAEzH,kCAAkC;AAClC,MAAM,CAAC,MAAM,eAAe,GAAG;IAC3B,IAAI,EAAE,CAAC,EAAE,4DAA4D;IACrE,MAAM,EAAE,CAAC,EAAE,2DAA2D;CACzE,CAAC"}
|
package/build/server/server.d.ts
CHANGED
|
@@ -3,15 +3,13 @@ import * as realWarpsocket from 'warpsocket';
|
|
|
3
3
|
export declare const logLevel: number;
|
|
4
4
|
/** @internal Warpsocket implementation; swapped to FakeWarpSocket in test mode. */
|
|
5
5
|
export declare let warpsocket: typeof realWarpsocket;
|
|
6
|
-
/** @internal Type alias for Edinburgh model classes */
|
|
7
|
-
type ModelClass = typeof E.Model<unknown>;
|
|
8
6
|
/**
|
|
9
7
|
* Base class for stream types created by {@link createStreamType}.
|
|
10
8
|
* @typeParam T - The projected model type
|
|
11
9
|
* @internal
|
|
12
10
|
*/
|
|
13
11
|
export declare abstract class StreamTypeBase<T> {
|
|
14
|
-
_instance: E.Model<
|
|
12
|
+
_instance: E.Model<unknown> & T;
|
|
15
13
|
/** @internal */
|
|
16
14
|
static fields: {
|
|
17
15
|
[key: string]: true | number;
|
|
@@ -20,30 +18,31 @@ export declare abstract class StreamTypeBase<T> {
|
|
|
20
18
|
static id: number;
|
|
21
19
|
/** @internal */
|
|
22
20
|
static cache: number | undefined;
|
|
23
|
-
constructor(_instance: E.Model<
|
|
21
|
+
constructor(_instance: E.Model<unknown> & T);
|
|
24
22
|
toString(): string;
|
|
25
23
|
}
|
|
26
24
|
/**
|
|
27
25
|
* Type-safe selector for specifying which model fields to stream to clients.
|
|
28
26
|
* Use `true` to include a field, or an object to select nested fields in linked models.
|
|
27
|
+
* Set<U> and Record<string, U> fields take a selection for U (applied to every element).
|
|
29
28
|
*
|
|
30
29
|
* @typeParam T - The model type
|
|
31
30
|
*/
|
|
32
|
-
type FieldSelection<T> = T extends ReadonlyArray<infer U> ? true | FieldSelection<U> : T extends Array<infer U> ? true | FieldSelection<U> : T extends object ? true | {
|
|
31
|
+
type FieldSelection<T> = T extends ReadonlyArray<infer U> ? true | FieldSelection<U> : T extends Array<infer U> ? true | FieldSelection<U> : T extends ReadonlySet<infer U> ? true | FieldSelection<U> : string extends keyof T ? T extends Record<string, infer U> ? true | FieldSelection<U> : true : T extends object ? true | {
|
|
33
32
|
[K in keyof T]?: FieldSelection<T[K]>;
|
|
34
33
|
} : true;
|
|
35
34
|
/**
|
|
36
35
|
* Validates field selection compatibility at compile time.
|
|
37
36
|
* @internal
|
|
38
37
|
*/
|
|
39
|
-
type ValidateSelection<T, S> = T extends ReadonlyArray<infer U> ? S extends true ? true : ValidateSelection<U, S> : T extends Array<infer U> ? S extends true ? true : ValidateSelection<U, S> : T extends object ? S extends true ? true : S extends object ? {
|
|
38
|
+
type ValidateSelection<T, S> = T extends ReadonlyArray<infer U> ? S extends true ? true : ValidateSelection<U, S> : T extends Array<infer U> ? S extends true ? true : ValidateSelection<U, S> : T extends ReadonlySet<infer U> ? S extends true ? true : ValidateSelection<U, S> : string extends keyof T ? T extends Record<string, infer U> ? S extends true ? true : ValidateSelection<U, S> : never : T extends object ? S extends true ? true : S extends object ? {
|
|
40
39
|
[K in keyof S]-?: K extends keyof T ? ValidateSelection<T[K], S[K]> : never;
|
|
41
40
|
} : never : S extends true ? true : never;
|
|
42
41
|
/**
|
|
43
42
|
* Computes the resulting type after applying a field selection.
|
|
44
43
|
* @internal
|
|
45
44
|
*/
|
|
46
|
-
type Project<T, S> = S extends true ? T : T extends ReadonlyArray<infer U> ? ReadonlyArray<Project<U, S>> : T extends Array<infer U> ? Array<Project<U, S>> : T extends object ? {
|
|
45
|
+
type Project<T, S> = S extends true ? T : T extends ReadonlyArray<infer U> ? ReadonlyArray<Project<U, S>> : T extends Array<infer U> ? Array<Project<U, S>> : T extends ReadonlySet<infer U> ? Project<U, S>[] : string extends keyof T ? T extends Record<string, infer U> ? Record<string, Project<U, S>> : T : T extends object ? {
|
|
47
46
|
[K in Extract<keyof S, keyof T>]: Project<T[K], S[K & keyof T]>;
|
|
48
47
|
} : T;
|
|
49
48
|
/**
|
|
@@ -63,13 +62,12 @@ type Project<T, S> = S extends true ? T : T extends ReadonlyArray<infer U> ? Rea
|
|
|
63
62
|
*
|
|
64
63
|
* @example
|
|
65
64
|
* ```ts
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
* }
|
|
65
|
+
* const Person = E.defineModel('Person', class {
|
|
66
|
+
* name = E.field(E.string);
|
|
67
|
+
* age = E.field(E.number);
|
|
68
|
+
* password = E.field(E.string);
|
|
69
|
+
* friends = E.field(E.array(E.link(() => Person)));
|
|
70
|
+
* }, { pk: 'name' });
|
|
73
71
|
*
|
|
74
72
|
* // Exclude password, include friends' names; cache 30s
|
|
75
73
|
* const PersonStream = createStreamType(Person, {
|
|
@@ -79,21 +77,18 @@ type Project<T, S> = S extends true ? T : T extends ReadonlyArray<infer U> ? Rea
|
|
|
79
77
|
* }, { cache: 30 });
|
|
80
78
|
*
|
|
81
79
|
* export function streamPerson() {
|
|
82
|
-
* const person = Person.
|
|
80
|
+
* const person = Person.get('Alice')!;
|
|
83
81
|
* return new PersonStream(person);
|
|
84
82
|
* }
|
|
85
83
|
* ```
|
|
86
84
|
*/
|
|
87
|
-
export declare function createStreamType<T, S extends FieldSelection<T>>(Model:
|
|
85
|
+
export declare function createStreamType<T, S extends FieldSelection<T>>(Model: E.AnyModelClass & (new (...args: any[]) => T), selection: S & ValidateSelection<T, S>, options?: {
|
|
88
86
|
cache?: number;
|
|
89
87
|
}): {
|
|
90
|
-
new (
|
|
91
|
-
_instance: E.Model<any> & Project<T, S>;
|
|
92
|
-
toString(): string;
|
|
93
|
-
};
|
|
94
|
-
fields: Record<string, number | true>;
|
|
88
|
+
new (instance: T): StreamTypeBase<Project<T, S>>;
|
|
95
89
|
id: number;
|
|
96
|
-
|
|
90
|
+
fields: Record<string, true | number>;
|
|
91
|
+
cache?: number;
|
|
97
92
|
};
|
|
98
93
|
/**
|
|
99
94
|
* Sends (updated) data for `model` to `target`.
|
|
@@ -109,6 +104,10 @@ export declare function pushModel(target: number | Uint8Array | number[], model:
|
|
|
109
104
|
* Wraps a server-side API object to create a stateful, type-safe proxy accessible from clients.
|
|
110
105
|
* Use for authentication, sessions, or any stateful context that persists across RPC calls.
|
|
111
106
|
*
|
|
107
|
+
* If the API object has an `onDrop()` method, it is called when the proxy is dropped, either
|
|
108
|
+
* because the client cancelled the request (scope cleanup) or the WebSocket disconnected.
|
|
109
|
+
* Use this to clean up server-side state kept on behalf of the client.
|
|
110
|
+
*
|
|
112
111
|
* @typeParam API - The server-side API object type
|
|
113
112
|
* @typeParam RETURN - The value type returned to the client
|
|
114
113
|
*
|
|
@@ -117,6 +116,7 @@ export declare function pushModel(target: number | Uint8Array | number[], model:
|
|
|
117
116
|
* export class UserAPI {
|
|
118
117
|
* constructor(public user: User) {}
|
|
119
118
|
* getSecret() { return this.user.secret; }
|
|
119
|
+
* onDrop() { console.log('client gone'); }
|
|
120
120
|
* }
|
|
121
121
|
*
|
|
122
122
|
* export async function authenticate(token: string) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../server/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,WAAW,CAAC;AAE/B,OAAO,KAAK,cAAc,MAAM,YAAY,CAAC;AAO7C,eAAO,MAAM,QAAQ,QAAwD,CAAC;AAE9E,mFAAmF;AACnF,eAAO,IAAI,UAAU,EAAE,OAAO,cAA+B,CAAC;AAa9D
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../server/server.ts"],"names":[],"mappings":"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"}
|
package/build/server/server.js
CHANGED
|
@@ -82,13 +82,12 @@ function getIdForData(namespace, ...data) {
|
|
|
82
82
|
*
|
|
83
83
|
* @example
|
|
84
84
|
* ```ts
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
* }
|
|
85
|
+
* const Person = E.defineModel('Person', class {
|
|
86
|
+
* name = E.field(E.string);
|
|
87
|
+
* age = E.field(E.number);
|
|
88
|
+
* password = E.field(E.string);
|
|
89
|
+
* friends = E.field(E.array(E.link(() => Person)));
|
|
90
|
+
* }, { pk: 'name' });
|
|
92
91
|
*
|
|
93
92
|
* // Exclude password, include friends' names; cache 30s
|
|
94
93
|
* const PersonStream = createStreamType(Person, {
|
|
@@ -98,7 +97,7 @@ function getIdForData(namespace, ...data) {
|
|
|
98
97
|
* }, { cache: 30 });
|
|
99
98
|
*
|
|
100
99
|
* export function streamPerson() {
|
|
101
|
-
* const person = Person.
|
|
100
|
+
* const person = Person.get('Alice')!;
|
|
102
101
|
* return new PersonStream(person);
|
|
103
102
|
* }
|
|
104
103
|
* ```
|
|
@@ -142,7 +141,7 @@ function writeModelField(pack, value, streamTypeId) {
|
|
|
142
141
|
else if (value instanceof E.Model) {
|
|
143
142
|
pack.writeCustom('model', value.getPrimaryKeyHash() + streamTypeId);
|
|
144
143
|
}
|
|
145
|
-
else if (Array.isArray(value)) {
|
|
144
|
+
else if (Array.isArray(value) || value instanceof Set) {
|
|
146
145
|
pack.writeCollection('array', () => {
|
|
147
146
|
for (const item of value)
|
|
148
147
|
writeModelField(pack, item, streamTypeId);
|
|
@@ -161,7 +160,7 @@ function writeModelField(pack, value, streamTypeId) {
|
|
|
161
160
|
function updateLinkDeltas(value, linkDeltas, streamTypeId, delta) {
|
|
162
161
|
if (typeof value !== 'object' || value == null)
|
|
163
162
|
return;
|
|
164
|
-
if (Array.isArray(value)) {
|
|
163
|
+
if (Array.isArray(value) || value instanceof Set) {
|
|
165
164
|
for (const item of value)
|
|
166
165
|
updateLinkDeltas(item, linkDeltas, streamTypeId, delta);
|
|
167
166
|
}
|
|
@@ -224,7 +223,7 @@ export function sendModel(target, model, commitId, StreamType, changed) {
|
|
|
224
223
|
if (typeof changed === 'object' && !changed.hasOwnProperty(fieldName))
|
|
225
224
|
continue;
|
|
226
225
|
let streamIndex = StreamType.fields[fieldName];
|
|
227
|
-
|
|
226
|
+
let fieldValue = model[fieldName];
|
|
228
227
|
mustSend = true;
|
|
229
228
|
if (typeof streamIndex === 'number') {
|
|
230
229
|
pack.write(fieldName);
|
|
@@ -270,6 +269,10 @@ export function pushModel(target, model, commitId, SubStreamType, delta) {
|
|
|
270
269
|
* Wraps a server-side API object to create a stateful, type-safe proxy accessible from clients.
|
|
271
270
|
* Use for authentication, sessions, or any stateful context that persists across RPC calls.
|
|
272
271
|
*
|
|
272
|
+
* If the API object has an `onDrop()` method, it is called when the proxy is dropped, either
|
|
273
|
+
* because the client cancelled the request (scope cleanup) or the WebSocket disconnected.
|
|
274
|
+
* Use this to clean up server-side state kept on behalf of the client.
|
|
275
|
+
*
|
|
273
276
|
* @typeParam API - The server-side API object type
|
|
274
277
|
* @typeParam RETURN - The value type returned to the client
|
|
275
278
|
*
|
|
@@ -278,6 +281,7 @@ export function pushModel(target, model, commitId, SubStreamType, delta) {
|
|
|
278
281
|
* export class UserAPI {
|
|
279
282
|
* constructor(public user: User) {}
|
|
280
283
|
* getSecret() { return this.user.secret; }
|
|
284
|
+
* onDrop() { console.log('client gone'); }
|
|
281
285
|
* }
|
|
282
286
|
*
|
|
283
287
|
* export async function authenticate(token: string) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../server/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,WAAW,CAAC;AAC/B,OAAO,QAAQ,MAAM,oBAAoB,CAAC;AAC1C,OAAO,KAAK,cAAc,MAAM,YAAY,CAAC;AAE7C,0CAA0C;AAC1C,0BAA0B;AAC1B,4EAA4E;AAC5E,sEAAsE;AACtE,4EAA4E;AAC5E,MAAM,CAAC,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;AAE9E,mFAAmF;AACnF,MAAM,CAAC,IAAI,UAAU,GAA0B,cAAc,CAAC;AAE9D,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAExC,MAAM,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;AAExF,+DAA+D;AAC/D,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAE7B,qEAAqE;AACrE,MAAM,mBAAmB,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../server/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,5 +7,5 @@ export interface Request {
|
|
|
7
7
|
export declare function handleOpen(socketId: number, ip: string): void;
|
|
8
8
|
export declare function handleStart(apiFile: any): Promise<void>;
|
|
9
9
|
export declare function handleBinaryMessage(message: Uint8Array, socketId: number): Promise<void>;
|
|
10
|
-
export declare function handleClose(socketId: number): void
|
|
10
|
+
export declare function handleClose(socketId: number): Promise<void>;
|
|
11
11
|
//# sourceMappingURL=wshandler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wshandler.d.ts","sourceRoot":"","sources":["../../server/wshandler.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,aAAa,+BAAsC,CAAC;AAEjE,MAAM,WAAW,OAAO;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,UAAU,CAAC;CACrB;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAEtD;AAWD,wBAAsB,WAAW,CAAC,OAAO,EAAE,GAAG,iBAG7C;AAGD,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"wshandler.d.ts","sourceRoot":"","sources":["../../server/wshandler.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,aAAa,+BAAsC,CAAC;AAEjE,MAAM,WAAW,OAAO;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,UAAU,CAAC;CACrB;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAEtD;AAWD,wBAAsB,WAAW,CAAC,OAAO,EAAE,GAAG,iBAG7C;AAGD,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,iBA2H9E;AAED,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,iBAkBjD"}
|
|
@@ -28,8 +28,19 @@ export async function handleBinaryMessage(message, socketId) {
|
|
|
28
28
|
// Delete server proxy object, if any
|
|
29
29
|
const cancelRequestId = pack.readPositiveInt();
|
|
30
30
|
const proxies = socketProxies.get(socketId);
|
|
31
|
-
if (proxies)
|
|
31
|
+
if (proxies) {
|
|
32
|
+
/** Call `onDrop()` on a proxy if it has one. Runs in a transaction; errors are logged. */
|
|
33
|
+
const proxy = proxies.get(cancelRequestId);
|
|
32
34
|
proxies.delete(cancelRequestId);
|
|
35
|
+
if (proxy && typeof proxy.onDrop === 'function') {
|
|
36
|
+
try {
|
|
37
|
+
await E.transact(() => proxy.onDrop());
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
console.error('cancel request onDrop error', err);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
33
44
|
// Delete any virtual sockets created for this request
|
|
34
45
|
for (const virtualSocketId of pack.read() || []) {
|
|
35
46
|
// The second argument makes sure we're not deleting virtual
|
|
@@ -75,12 +86,13 @@ export async function handleBinaryMessage(message, socketId) {
|
|
|
75
86
|
return sendError(socketId, requestId, `Params must be an array`);
|
|
76
87
|
}
|
|
77
88
|
try {
|
|
78
|
-
let
|
|
89
|
+
let pendingPacket;
|
|
79
90
|
await E.transact(async () => {
|
|
80
91
|
let response = await func.apply(api, params);
|
|
81
92
|
if (logLevel >= 2)
|
|
82
93
|
console.log('[lowlander] Called', methodName, 'with', params, '->', typeof response === 'object' && response ? response.toString() : JSON.stringify(response));
|
|
83
|
-
// Result processing/
|
|
94
|
+
// Result processing/serialization should be within the transaction, as it may involve (lazy) loading models.
|
|
95
|
+
// The actual socket send remains deferred until after commit.
|
|
84
96
|
if (response instanceof ServerProxy) {
|
|
85
97
|
let proxies = socketProxies.get(socketId);
|
|
86
98
|
if (!proxies)
|
|
@@ -88,7 +100,18 @@ export async function handleBinaryMessage(message, socketId) {
|
|
|
88
100
|
if (logLevel >= 3)
|
|
89
101
|
console.log('[lowlander] Setting proxy id', requestId, 'for socket', socketId);
|
|
90
102
|
proxies.set(requestId, response.api);
|
|
91
|
-
|
|
103
|
+
if (response.value instanceof StreamTypeBase) {
|
|
104
|
+
const StreamType = response.value.constructor;
|
|
105
|
+
const instance = response.value._instance;
|
|
106
|
+
const virtualSocketId = warpsocket.createVirtualSocket(socketId, DataPack.createUint8Array(requestId, SERVER_MESSAGES.model_data));
|
|
107
|
+
virtualSocketIds.push(virtualSocketId);
|
|
108
|
+
pushModel(virtualSocketId, instance, 0, StreamType, 1);
|
|
109
|
+
const cacheMs = StreamType.cache !== undefined ? StreamType.cache * 1000 : undefined;
|
|
110
|
+
pendingPacket = DataPack.createUint8Array(requestId, SERVER_MESSAGES.response_proxy_model, virtualSocketIds, instance.getPrimaryKeyHash() + StreamType.id, cacheMs);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
pendingPacket = DataPack.createUint8Array(requestId, SERVER_MESSAGES.response_proxy, response.value, virtualSocketIds);
|
|
114
|
+
}
|
|
92
115
|
}
|
|
93
116
|
else if (response instanceof StreamTypeBase) {
|
|
94
117
|
const StreamType = response.constructor;
|
|
@@ -100,15 +123,15 @@ export async function handleBinaryMessage(message, socketId) {
|
|
|
100
123
|
pushModel(virtualSocketId, instance, 0, StreamType, 1);
|
|
101
124
|
// Then respond, indicating which row should be top level
|
|
102
125
|
const cacheMs = StreamType.cache !== undefined ? StreamType.cache * 1000 : undefined;
|
|
103
|
-
|
|
126
|
+
pendingPacket = DataPack.createUint8Array(requestId, SERVER_MESSAGES.response_model, virtualSocketIds, instance.getPrimaryKeyHash() + StreamType.id, cacheMs);
|
|
104
127
|
}
|
|
105
128
|
else {
|
|
106
129
|
// A regular result
|
|
107
|
-
|
|
130
|
+
pendingPacket = DataPack.createUint8Array(requestId, SERVER_MESSAGES.response, response, virtualSocketIds);
|
|
108
131
|
}
|
|
109
132
|
});
|
|
110
133
|
// Send response after transaction has committed
|
|
111
|
-
|
|
134
|
+
warpsocket.send(socketId, pendingPacket);
|
|
112
135
|
}
|
|
113
136
|
catch (error) {
|
|
114
137
|
console.error('RPC error', error);
|
|
@@ -119,9 +142,26 @@ export async function handleBinaryMessage(message, socketId) {
|
|
|
119
142
|
sendError(socketId, requestId, `Unknown message type: ${type}`);
|
|
120
143
|
}
|
|
121
144
|
}
|
|
122
|
-
export function handleClose(socketId) {
|
|
145
|
+
export async function handleClose(socketId) {
|
|
123
146
|
if (logLevel >= 1)
|
|
124
147
|
console.log('[lowlander] Client disconnected', socketId);
|
|
148
|
+
const proxies = socketProxies.get(socketId);
|
|
149
|
+
if (!proxies)
|
|
150
|
+
return;
|
|
125
151
|
socketProxies.delete(socketId);
|
|
152
|
+
if (!proxies.values().some(p => typeof p.onDrop === 'function'))
|
|
153
|
+
return;
|
|
154
|
+
await E.transact(async () => {
|
|
155
|
+
for (const proxy of proxies.values()) {
|
|
156
|
+
if (typeof proxy?.onDrop === 'function') {
|
|
157
|
+
try {
|
|
158
|
+
await proxy.onDrop();
|
|
159
|
+
}
|
|
160
|
+
catch (err) {
|
|
161
|
+
console.error('handleClose onDrop error', err);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
});
|
|
126
166
|
}
|
|
127
167
|
//# sourceMappingURL=wshandler.js.map
|