@epic-web/workshop-presence 5.2.0 → 5.3.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/dist/esm/presence.d.ts +60 -0
- package/dist/esm/presence.d.ts.map +1 -1
- package/dist/esm/presence.js +4 -0
- package/dist/esm/presence.js.map +1 -1
- package/dist/esm/presence.server.d.ts +3 -0
- package/dist/esm/presence.server.d.ts.map +1 -1
- package/dist/esm/server.d.ts +6 -0
- package/dist/esm/server.d.ts.map +1 -1
- package/dist/esm/server.js +2 -1
- package/dist/esm/server.js.map +1 -1
- package/package.json +2 -2
package/dist/esm/presence.d.ts
CHANGED
|
@@ -3,7 +3,10 @@ export declare const partykitRoom = "epic-web-presence";
|
|
|
3
3
|
export declare const partykitBaseUrl = "https://epic-web-presence.kentcdodds.partykit.dev/parties/main/epic-web-presence";
|
|
4
4
|
export declare const UserSchema: z.ZodObject<{
|
|
5
5
|
id: z.ZodString;
|
|
6
|
+
hasAccess: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
|
|
6
7
|
avatarUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
8
|
+
imageUrlSmall: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
9
|
+
imageUrlLarge: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
7
10
|
name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
8
11
|
location: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
9
12
|
workshopTitle: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
@@ -40,7 +43,10 @@ export declare const UserSchema: z.ZodObject<{
|
|
|
40
43
|
}>>>;
|
|
41
44
|
}, "strip", z.ZodTypeAny, {
|
|
42
45
|
id: string;
|
|
46
|
+
hasAccess?: boolean | null | undefined;
|
|
43
47
|
avatarUrl?: string | null | undefined;
|
|
48
|
+
imageUrlSmall?: string | null | undefined;
|
|
49
|
+
imageUrlLarge?: string | null | undefined;
|
|
44
50
|
name?: string | null | undefined;
|
|
45
51
|
location?: {
|
|
46
52
|
workshopTitle?: string | null | undefined;
|
|
@@ -53,7 +59,10 @@ export declare const UserSchema: z.ZodObject<{
|
|
|
53
59
|
} | null | undefined;
|
|
54
60
|
}, {
|
|
55
61
|
id: string;
|
|
62
|
+
hasAccess?: boolean | null | undefined;
|
|
56
63
|
avatarUrl?: string | null | undefined;
|
|
64
|
+
imageUrlSmall?: string | null | undefined;
|
|
65
|
+
imageUrlLarge?: string | null | undefined;
|
|
57
66
|
name?: string | null | undefined;
|
|
58
67
|
location?: {
|
|
59
68
|
workshopTitle?: string | null | undefined;
|
|
@@ -88,7 +97,10 @@ export declare const MessageSchema: z.ZodUnion<[z.ZodUnion<[z.ZodObject<{
|
|
|
88
97
|
type: z.ZodLiteral<"add-user">;
|
|
89
98
|
payload: z.ZodObject<{
|
|
90
99
|
id: z.ZodString;
|
|
100
|
+
hasAccess: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
|
|
91
101
|
avatarUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
102
|
+
imageUrlSmall: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
103
|
+
imageUrlLarge: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
92
104
|
name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
93
105
|
location: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
94
106
|
workshopTitle: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
@@ -125,7 +137,10 @@ export declare const MessageSchema: z.ZodUnion<[z.ZodUnion<[z.ZodObject<{
|
|
|
125
137
|
}>>>;
|
|
126
138
|
}, "strip", z.ZodTypeAny, {
|
|
127
139
|
id: string;
|
|
140
|
+
hasAccess?: boolean | null | undefined;
|
|
128
141
|
avatarUrl?: string | null | undefined;
|
|
142
|
+
imageUrlSmall?: string | null | undefined;
|
|
143
|
+
imageUrlLarge?: string | null | undefined;
|
|
129
144
|
name?: string | null | undefined;
|
|
130
145
|
location?: {
|
|
131
146
|
workshopTitle?: string | null | undefined;
|
|
@@ -138,7 +153,10 @@ export declare const MessageSchema: z.ZodUnion<[z.ZodUnion<[z.ZodObject<{
|
|
|
138
153
|
} | null | undefined;
|
|
139
154
|
}, {
|
|
140
155
|
id: string;
|
|
156
|
+
hasAccess?: boolean | null | undefined;
|
|
141
157
|
avatarUrl?: string | null | undefined;
|
|
158
|
+
imageUrlSmall?: string | null | undefined;
|
|
159
|
+
imageUrlLarge?: string | null | undefined;
|
|
142
160
|
name?: string | null | undefined;
|
|
143
161
|
location?: {
|
|
144
162
|
workshopTitle?: string | null | undefined;
|
|
@@ -154,7 +172,10 @@ export declare const MessageSchema: z.ZodUnion<[z.ZodUnion<[z.ZodObject<{
|
|
|
154
172
|
type: "add-user";
|
|
155
173
|
payload: {
|
|
156
174
|
id: string;
|
|
175
|
+
hasAccess?: boolean | null | undefined;
|
|
157
176
|
avatarUrl?: string | null | undefined;
|
|
177
|
+
imageUrlSmall?: string | null | undefined;
|
|
178
|
+
imageUrlLarge?: string | null | undefined;
|
|
158
179
|
name?: string | null | undefined;
|
|
159
180
|
location?: {
|
|
160
181
|
workshopTitle?: string | null | undefined;
|
|
@@ -170,7 +191,10 @@ export declare const MessageSchema: z.ZodUnion<[z.ZodUnion<[z.ZodObject<{
|
|
|
170
191
|
type: "add-user";
|
|
171
192
|
payload: {
|
|
172
193
|
id: string;
|
|
194
|
+
hasAccess?: boolean | null | undefined;
|
|
173
195
|
avatarUrl?: string | null | undefined;
|
|
196
|
+
imageUrlSmall?: string | null | undefined;
|
|
197
|
+
imageUrlLarge?: string | null | undefined;
|
|
174
198
|
name?: string | null | undefined;
|
|
175
199
|
location?: {
|
|
176
200
|
workshopTitle?: string | null | undefined;
|
|
@@ -187,7 +211,10 @@ export declare const MessageSchema: z.ZodUnion<[z.ZodUnion<[z.ZodObject<{
|
|
|
187
211
|
payload: z.ZodObject<{
|
|
188
212
|
users: z.ZodArray<z.ZodObject<{
|
|
189
213
|
id: z.ZodString;
|
|
214
|
+
hasAccess: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
|
|
190
215
|
avatarUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
216
|
+
imageUrlSmall: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
217
|
+
imageUrlLarge: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
191
218
|
name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
192
219
|
location: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
193
220
|
workshopTitle: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
@@ -224,7 +251,10 @@ export declare const MessageSchema: z.ZodUnion<[z.ZodUnion<[z.ZodObject<{
|
|
|
224
251
|
}>>>;
|
|
225
252
|
}, "strip", z.ZodTypeAny, {
|
|
226
253
|
id: string;
|
|
254
|
+
hasAccess?: boolean | null | undefined;
|
|
227
255
|
avatarUrl?: string | null | undefined;
|
|
256
|
+
imageUrlSmall?: string | null | undefined;
|
|
257
|
+
imageUrlLarge?: string | null | undefined;
|
|
228
258
|
name?: string | null | undefined;
|
|
229
259
|
location?: {
|
|
230
260
|
workshopTitle?: string | null | undefined;
|
|
@@ -237,7 +267,10 @@ export declare const MessageSchema: z.ZodUnion<[z.ZodUnion<[z.ZodObject<{
|
|
|
237
267
|
} | null | undefined;
|
|
238
268
|
}, {
|
|
239
269
|
id: string;
|
|
270
|
+
hasAccess?: boolean | null | undefined;
|
|
240
271
|
avatarUrl?: string | null | undefined;
|
|
272
|
+
imageUrlSmall?: string | null | undefined;
|
|
273
|
+
imageUrlLarge?: string | null | undefined;
|
|
241
274
|
name?: string | null | undefined;
|
|
242
275
|
location?: {
|
|
243
276
|
workshopTitle?: string | null | undefined;
|
|
@@ -252,7 +285,10 @@ export declare const MessageSchema: z.ZodUnion<[z.ZodUnion<[z.ZodObject<{
|
|
|
252
285
|
}, "strip", z.ZodTypeAny, {
|
|
253
286
|
users: {
|
|
254
287
|
id: string;
|
|
288
|
+
hasAccess?: boolean | null | undefined;
|
|
255
289
|
avatarUrl?: string | null | undefined;
|
|
290
|
+
imageUrlSmall?: string | null | undefined;
|
|
291
|
+
imageUrlLarge?: string | null | undefined;
|
|
256
292
|
name?: string | null | undefined;
|
|
257
293
|
location?: {
|
|
258
294
|
workshopTitle?: string | null | undefined;
|
|
@@ -267,7 +303,10 @@ export declare const MessageSchema: z.ZodUnion<[z.ZodUnion<[z.ZodObject<{
|
|
|
267
303
|
}, {
|
|
268
304
|
users: {
|
|
269
305
|
id: string;
|
|
306
|
+
hasAccess?: boolean | null | undefined;
|
|
270
307
|
avatarUrl?: string | null | undefined;
|
|
308
|
+
imageUrlSmall?: string | null | undefined;
|
|
309
|
+
imageUrlLarge?: string | null | undefined;
|
|
271
310
|
name?: string | null | undefined;
|
|
272
311
|
location?: {
|
|
273
312
|
workshopTitle?: string | null | undefined;
|
|
@@ -285,7 +324,10 @@ export declare const MessageSchema: z.ZodUnion<[z.ZodUnion<[z.ZodObject<{
|
|
|
285
324
|
payload: {
|
|
286
325
|
users: {
|
|
287
326
|
id: string;
|
|
327
|
+
hasAccess?: boolean | null | undefined;
|
|
288
328
|
avatarUrl?: string | null | undefined;
|
|
329
|
+
imageUrlSmall?: string | null | undefined;
|
|
330
|
+
imageUrlLarge?: string | null | undefined;
|
|
289
331
|
name?: string | null | undefined;
|
|
290
332
|
location?: {
|
|
291
333
|
workshopTitle?: string | null | undefined;
|
|
@@ -303,7 +345,10 @@ export declare const MessageSchema: z.ZodUnion<[z.ZodUnion<[z.ZodObject<{
|
|
|
303
345
|
payload: {
|
|
304
346
|
users: {
|
|
305
347
|
id: string;
|
|
348
|
+
hasAccess?: boolean | null | undefined;
|
|
306
349
|
avatarUrl?: string | null | undefined;
|
|
350
|
+
imageUrlSmall?: string | null | undefined;
|
|
351
|
+
imageUrlLarge?: string | null | undefined;
|
|
307
352
|
name?: string | null | undefined;
|
|
308
353
|
location?: {
|
|
309
354
|
workshopTitle?: string | null | undefined;
|
|
@@ -322,7 +367,10 @@ export type User = z.infer<typeof UserSchema>;
|
|
|
322
367
|
export declare const PresenceSchema: z.ZodObject<{
|
|
323
368
|
users: z.ZodArray<z.ZodObject<{
|
|
324
369
|
id: z.ZodString;
|
|
370
|
+
hasAccess: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
|
|
325
371
|
avatarUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
372
|
+
imageUrlSmall: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
373
|
+
imageUrlLarge: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
326
374
|
name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
327
375
|
location: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
328
376
|
workshopTitle: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
@@ -359,7 +407,10 @@ export declare const PresenceSchema: z.ZodObject<{
|
|
|
359
407
|
}>>>;
|
|
360
408
|
}, "strip", z.ZodTypeAny, {
|
|
361
409
|
id: string;
|
|
410
|
+
hasAccess?: boolean | null | undefined;
|
|
362
411
|
avatarUrl?: string | null | undefined;
|
|
412
|
+
imageUrlSmall?: string | null | undefined;
|
|
413
|
+
imageUrlLarge?: string | null | undefined;
|
|
363
414
|
name?: string | null | undefined;
|
|
364
415
|
location?: {
|
|
365
416
|
workshopTitle?: string | null | undefined;
|
|
@@ -372,7 +423,10 @@ export declare const PresenceSchema: z.ZodObject<{
|
|
|
372
423
|
} | null | undefined;
|
|
373
424
|
}, {
|
|
374
425
|
id: string;
|
|
426
|
+
hasAccess?: boolean | null | undefined;
|
|
375
427
|
avatarUrl?: string | null | undefined;
|
|
428
|
+
imageUrlSmall?: string | null | undefined;
|
|
429
|
+
imageUrlLarge?: string | null | undefined;
|
|
376
430
|
name?: string | null | undefined;
|
|
377
431
|
location?: {
|
|
378
432
|
workshopTitle?: string | null | undefined;
|
|
@@ -387,7 +441,10 @@ export declare const PresenceSchema: z.ZodObject<{
|
|
|
387
441
|
}, "strip", z.ZodTypeAny, {
|
|
388
442
|
users: {
|
|
389
443
|
id: string;
|
|
444
|
+
hasAccess?: boolean | null | undefined;
|
|
390
445
|
avatarUrl?: string | null | undefined;
|
|
446
|
+
imageUrlSmall?: string | null | undefined;
|
|
447
|
+
imageUrlLarge?: string | null | undefined;
|
|
391
448
|
name?: string | null | undefined;
|
|
392
449
|
location?: {
|
|
393
450
|
workshopTitle?: string | null | undefined;
|
|
@@ -402,7 +459,10 @@ export declare const PresenceSchema: z.ZodObject<{
|
|
|
402
459
|
}, {
|
|
403
460
|
users: {
|
|
404
461
|
id: string;
|
|
462
|
+
hasAccess?: boolean | null | undefined;
|
|
405
463
|
avatarUrl?: string | null | undefined;
|
|
464
|
+
imageUrlSmall?: string | null | undefined;
|
|
465
|
+
imageUrlLarge?: string | null | undefined;
|
|
406
466
|
name?: string | null | undefined;
|
|
407
467
|
location?: {
|
|
408
468
|
workshopTitle?: string | null | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presence.d.ts","sourceRoot":"","sources":["../../src/presence.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,eAAO,MAAM,YAAY,sBAAsB,CAAA;AAE/C,eAAO,MAAM,eAAe,qFAAmF,CAAA;AAE/G,eAAO,MAAM,UAAU
|
|
1
|
+
{"version":3,"file":"presence.d.ts","sourceRoot":"","sources":["../../src/presence.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,eAAO,MAAM,YAAY,sBAAsB,CAAA;AAE/C,eAAO,MAAM,eAAe,qFAAmF,CAAA;AAE/G,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0BrB,CAAA;AAEF,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAWxB,CAAA;AAEF,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAA;AAEnD,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAA;AAE7C,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAA2C,CAAA"}
|
package/dist/esm/presence.js
CHANGED
|
@@ -4,7 +4,11 @@ export const partykitRoom = 'epic-web-presence';
|
|
|
4
4
|
export const partykitBaseUrl = `https://epic-web-presence.kentcdodds.partykit.dev/parties/main/${partykitRoom}`;
|
|
5
5
|
export const UserSchema = z.object({
|
|
6
6
|
id: z.string(),
|
|
7
|
+
hasAccess: z.boolean().nullable().optional(),
|
|
8
|
+
// TODO: remove the avatarUrl field once people have updated their workshops
|
|
7
9
|
avatarUrl: z.string().nullable().optional(),
|
|
10
|
+
imageUrlSmall: z.string().nullable().optional(),
|
|
11
|
+
imageUrlLarge: z.string().nullable().optional(),
|
|
8
12
|
name: z.string().nullable().optional(),
|
|
9
13
|
location: z
|
|
10
14
|
.object({
|
package/dist/esm/presence.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presence.js","sourceRoot":"","sources":["../../src/presence.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,MAAM,CAAC,MAAM,YAAY,GAAG,mBAAmB,CAAA;AAC/C,sFAAsF;AACtF,MAAM,CAAC,MAAM,eAAe,GAAG,kEAAkE,YAAY,EAAE,CAAA;AAE/G,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC3C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACtC,QAAQ,EAAE,CAAC;SACT,MAAM,CAAC;QACP,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;QAC/C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;QACxC,QAAQ,EAAE,CAAC;aACT,MAAM,CAAC;YACP,IAAI,EAAE,CAAC;iBACL,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;iBACpD,QAAQ,EAAE;iBACV,QAAQ,EAAE;YACZ,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;YAChD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;SAC5C,CAAC;aACD,QAAQ,EAAE;aACV,QAAQ,EAAE;KACZ,CAAC;SACD,QAAQ,EAAE;SACV,QAAQ,EAAE;CACZ,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC;KAC5B,MAAM,CAAC;IACP,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;IAC9B,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;CACrC,CAAC;KACD,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;KAClE,EAAE,CACF,CAAC,CAAC,MAAM,CAAC;IACR,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC;IAC3B,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;CACjD,CAAC,CACF,CAAA;AAMF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA","sourcesContent":["import { z } from 'zod'\n\nexport const partykitRoom = 'epic-web-presence'\n// export const partykitBaseUrl = `http://127.0.0.1:1999/parties/main/${partykitRoom}`\nexport const partykitBaseUrl = `https://epic-web-presence.kentcdodds.partykit.dev/parties/main/${partykitRoom}`\n\nexport const UserSchema = z.object({\n\tid: z.string(),\n\tavatarUrl: z.string().nullable().optional(),\n\tname: z.string().nullable().optional(),\n\tlocation: z\n\t\t.object({\n\t\t\tworkshopTitle: z.string().nullable().optional(),\n\t\t\torigin: z.string().nullable().optional(),\n\t\t\texercise: z\n\t\t\t\t.object({\n\t\t\t\t\ttype: z\n\t\t\t\t\t\t.union([z.literal('problem'), z.literal('solution')])\n\t\t\t\t\t\t.nullable()\n\t\t\t\t\t\t.optional(),\n\t\t\t\t\texerciseNumber: z.number().nullable().optional(),\n\t\t\t\t\tstepNumber: z.number().nullable().optional(),\n\t\t\t\t})\n\t\t\t\t.nullable()\n\t\t\t\t.optional(),\n\t\t})\n\t\t.nullable()\n\t\t.optional(),\n})\n\nexport const MessageSchema = z\n\t.object({\n\t\ttype: z.literal('remove-user'),\n\t\tpayload: z.object({ id: z.string() }),\n\t})\n\t.or(z.object({ type: z.literal('add-user'), payload: UserSchema }))\n\t.or(\n\t\tz.object({\n\t\t\ttype: z.literal('presence'),\n\t\t\tpayload: z.object({ users: z.array(UserSchema) }),\n\t\t}),\n\t)\n\nexport type Message = z.infer<typeof MessageSchema>\n\nexport type User = z.infer<typeof UserSchema>\n\nexport const PresenceSchema = z.object({ users: z.array(UserSchema) })\n"]}
|
|
1
|
+
{"version":3,"file":"presence.js","sourceRoot":"","sources":["../../src/presence.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,MAAM,CAAC,MAAM,YAAY,GAAG,mBAAmB,CAAA;AAC/C,sFAAsF;AACtF,MAAM,CAAC,MAAM,eAAe,GAAG,kEAAkE,YAAY,EAAE,CAAA;AAE/G,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC5C,4EAA4E;IAC5E,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC3C,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC/C,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC/C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACtC,QAAQ,EAAE,CAAC;SACT,MAAM,CAAC;QACP,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;QAC/C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;QACxC,QAAQ,EAAE,CAAC;aACT,MAAM,CAAC;YACP,IAAI,EAAE,CAAC;iBACL,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;iBACpD,QAAQ,EAAE;iBACV,QAAQ,EAAE;YACZ,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;YAChD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;SAC5C,CAAC;aACD,QAAQ,EAAE;aACV,QAAQ,EAAE;KACZ,CAAC;SACD,QAAQ,EAAE;SACV,QAAQ,EAAE;CACZ,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC;KAC5B,MAAM,CAAC;IACP,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;IAC9B,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;CACrC,CAAC;KACD,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;KAClE,EAAE,CACF,CAAC,CAAC,MAAM,CAAC;IACR,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC;IAC3B,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;CACjD,CAAC,CACF,CAAA;AAMF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA","sourcesContent":["import { z } from 'zod'\n\nexport const partykitRoom = 'epic-web-presence'\n// export const partykitBaseUrl = `http://127.0.0.1:1999/parties/main/${partykitRoom}`\nexport const partykitBaseUrl = `https://epic-web-presence.kentcdodds.partykit.dev/parties/main/${partykitRoom}`\n\nexport const UserSchema = z.object({\n\tid: z.string(),\n\thasAccess: z.boolean().nullable().optional(),\n\t// TODO: remove the avatarUrl field once people have updated their workshops\n\tavatarUrl: z.string().nullable().optional(),\n\timageUrlSmall: z.string().nullable().optional(),\n\timageUrlLarge: z.string().nullable().optional(),\n\tname: z.string().nullable().optional(),\n\tlocation: z\n\t\t.object({\n\t\t\tworkshopTitle: z.string().nullable().optional(),\n\t\t\torigin: z.string().nullable().optional(),\n\t\t\texercise: z\n\t\t\t\t.object({\n\t\t\t\t\ttype: z\n\t\t\t\t\t\t.union([z.literal('problem'), z.literal('solution')])\n\t\t\t\t\t\t.nullable()\n\t\t\t\t\t\t.optional(),\n\t\t\t\t\texerciseNumber: z.number().nullable().optional(),\n\t\t\t\t\tstepNumber: z.number().nullable().optional(),\n\t\t\t\t})\n\t\t\t\t.nullable()\n\t\t\t\t.optional(),\n\t\t})\n\t\t.nullable()\n\t\t.optional(),\n})\n\nexport const MessageSchema = z\n\t.object({\n\t\ttype: z.literal('remove-user'),\n\t\tpayload: z.object({ id: z.string() }),\n\t})\n\t.or(z.object({ type: z.literal('add-user'), payload: UserSchema }))\n\t.or(\n\t\tz.object({\n\t\t\ttype: z.literal('presence'),\n\t\t\tpayload: z.object({ users: z.array(UserSchema) }),\n\t\t}),\n\t)\n\nexport type Message = z.infer<typeof MessageSchema>\n\nexport type User = z.infer<typeof UserSchema>\n\nexport const PresenceSchema = z.object({ users: z.array(UserSchema) })\n"]}
|
|
@@ -23,7 +23,10 @@ export declare function getPresentUsers(user?: User | null, { timings, request }
|
|
|
23
23
|
request?: Request;
|
|
24
24
|
}): Promise<{
|
|
25
25
|
id: string;
|
|
26
|
+
hasAccess?: boolean | null | undefined;
|
|
26
27
|
avatarUrl?: string | null | undefined;
|
|
28
|
+
imageUrlSmall?: string | null | undefined;
|
|
29
|
+
imageUrlLarge?: string | null | undefined;
|
|
27
30
|
name?: string | null | undefined;
|
|
28
31
|
location?: {
|
|
29
32
|
workshopTitle?: string | null | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presence.server.d.ts","sourceRoot":"","sources":["../../src/presence.server.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,wCAAwC,CAAA;AAErE,OAAO,EAIN,KAAK,IAAI,EACT,MAAM,eAAe,CAAA;AAEtB,eAAO,MAAM,aAAa;;;YAEpB,MAAM;mBACC,MAAM;cACX,MAAM,GAAG,IAAI,GAAG,SAAS;;YAF3B,MAAM;mBACC,MAAM;cACX,MAAM,GAAG,IAAI,GAAG,SAAS;;;YAF3B,MAAM;mBACC,MAAM;cACX,MAAM,GAAG,IAAI,GAAG,SAAS;;;CAEf,CAAA;AAElB,wBAAsB,eAAe,CACpC,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,EAClB,EAAE,OAAO,EAAE,OAAO,EAAE,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO
|
|
1
|
+
{"version":3,"file":"presence.server.d.ts","sourceRoot":"","sources":["../../src/presence.server.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,wCAAwC,CAAA;AAErE,OAAO,EAIN,KAAK,IAAI,EACT,MAAM,eAAe,CAAA;AAEtB,eAAO,MAAM,aAAa;;;YAEpB,MAAM;mBACC,MAAM;cACX,MAAM,GAAG,IAAI,GAAG,SAAS;;YAF3B,MAAM;mBACC,MAAM;cACX,MAAM,GAAG,IAAI,GAAG,SAAS;;;YAF3B,MAAM;mBACC,MAAM;cACX,MAAM,GAAG,IAAI,GAAG,SAAS;;;CAEf,CAAA;AAElB,wBAAsB,eAAe,CACpC,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,EAClB,EAAE,OAAO,EAAE,OAAO,EAAE,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO;;;;;;;;;;;;;;;;KA2CnE"}
|
package/dist/esm/server.d.ts
CHANGED
|
@@ -11,7 +11,10 @@ declare const _default: {
|
|
|
11
11
|
payload: {
|
|
12
12
|
users: {
|
|
13
13
|
id: string;
|
|
14
|
+
hasAccess?: boolean | null | undefined;
|
|
14
15
|
avatarUrl?: string | null | undefined;
|
|
16
|
+
imageUrlSmall?: string | null | undefined;
|
|
17
|
+
imageUrlLarge?: string | null | undefined;
|
|
15
18
|
name?: string | null | undefined;
|
|
16
19
|
location?: {
|
|
17
20
|
workshopTitle?: string | null | undefined;
|
|
@@ -27,7 +30,10 @@ declare const _default: {
|
|
|
27
30
|
};
|
|
28
31
|
getUsers(): {
|
|
29
32
|
id: string;
|
|
33
|
+
hasAccess?: boolean | null | undefined;
|
|
30
34
|
avatarUrl?: string | null | undefined;
|
|
35
|
+
imageUrlSmall?: string | null | undefined;
|
|
36
|
+
imageUrlLarge?: string | null | undefined;
|
|
31
37
|
name?: string | null | undefined;
|
|
32
38
|
location?: {
|
|
33
39
|
workshopTitle?: string | null | undefined;
|
package/dist/esm/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,iBAAiB,CAAA;;gBAwCzB,KAAK,CAAC,IAAI;iBANpB,KAAK,CAAC,aAAa;wBAIZ,KAAK,CAAC,IAAI
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,iBAAiB,CAAA;;gBAwCzB,KAAK,CAAC,IAAI;iBANpB,KAAK,CAAC,aAAa;wBAIZ,KAAK,CAAC,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAyCP,MAAM,UAAU,KAAK,CAAC,UAAU;uBAepC,KAAK,CAAC,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;;;AA7D5D,wBA+GyB"}
|
package/dist/esm/server.js
CHANGED
|
@@ -200,10 +200,11 @@ function generateUserListItem(user) {
|
|
|
200
200
|
: user.location?.origin
|
|
201
201
|
? user.location.origin
|
|
202
202
|
: 'Unknown location';
|
|
203
|
+
const accessLabel = typeof user.hasAccess === 'boolean' ? (user.hasAccess ? '🔑' : '🆓') : '';
|
|
203
204
|
return `
|
|
204
205
|
<li>
|
|
205
206
|
<img class="user-avatar" src="${avatarUrl}" alt="${name}" />
|
|
206
|
-
<strong>${name}</strong> - ${location}
|
|
207
|
+
<strong>${name}</strong> - ${location} ${accessLabel}
|
|
207
208
|
</li>
|
|
208
209
|
`;
|
|
209
210
|
}
|
package/dist/esm/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"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","sourcesContent":["import type * as Party from 'partykit/server'\nimport { z } from 'zod'\nimport { UserSchema } from './presence.js'\n\ntype User = z.infer<typeof UserSchema>\nconst ConnectionStateSchema = z\n\t.object({\n\t\tuser: UserSchema.nullable().optional(),\n\t})\n\t.nullable()\n\ntype ConnectionState = z.infer<typeof ConnectionStateSchema>\n\nconst MessageSchema = z\n\t.object({\n\t\ttype: z.literal('remove-user'),\n\t\tpayload: z.object({ id: z.string() }),\n\t})\n\t.or(z.object({ type: z.literal('add-user'), payload: UserSchema }))\n\t.or(\n\t\tz.object({\n\t\t\ttype: z.literal('add-anonymous-user'),\n\t\t\tpayload: z.object({ id: z.string() }),\n\t\t}),\n\t)\n\t.or(\n\t\tz.object({\n\t\t\ttype: z.literal('presence'),\n\t\t\tpayload: z.object({ users: z.array(UserSchema) }),\n\t\t}),\n\t)\ntype Message = z.infer<typeof MessageSchema>\n\nexport default (class Server implements Party.Server {\n\toptions: Party.ServerOptions = {\n\t\thibernate: true,\n\t}\n\n\treadonly party: Party.Room\n\n\tconstructor(party: Party.Room) {\n\t\tthis.party = party\n\t}\n\n\tonClose() {\n\t\tthis.updateUsers()\n\t}\n\n\tonError() {\n\t\tthis.updateUsers()\n\t}\n\n\tupdateUsers() {\n\t\tconst presenceMessage = JSON.stringify(this.getPresenceMessage())\n\t\tfor (const connection of this.party.getConnections()) {\n\t\t\tconnection.send(presenceMessage)\n\t\t}\n\t}\n\n\tgetPresenceMessage() {\n\t\treturn {\n\t\t\ttype: 'presence',\n\t\t\tpayload: { users: this.getUsers() },\n\t\t} satisfies Message\n\t}\n\n\tgetUsers() {\n\t\tconst users = new Map<string, z.infer<typeof UserSchema>>()\n\n\t\tfor (const connection of this.party.getConnections()) {\n\t\t\tconst state = getConnectionState(connection)\n\t\t\tif (state?.user) {\n\t\t\t\tusers.set(state.user.id, state.user)\n\t\t\t}\n\t\t}\n\n\t\treturn sortUsers(Array.from(users.values()))\n\t}\n\n\tonMessage(message: string, sender: Party.Connection) {\n\t\tconst result = MessageSchema.safeParse(JSON.parse(message))\n\t\tif (!result.success) return\n\n\t\tif (result.data.type === 'add-user') {\n\t\t\tshallowMergeConnectionState(sender, { user: result.data.payload })\n\t\t\tthis.updateUsers()\n\t\t} else if (result.data.type === 'remove-user') {\n\t\t\tsetConnectionState(sender, null)\n\t\t\tthis.updateUsers()\n\t\t} else if (result.data.type === 'add-anonymous-user') {\n\t\t\tsetConnectionState(sender, { user: result.data.payload })\n\t\t}\n\t}\n\n\tonRequest(req: Party.Request): Response | Promise<Response> {\n\t\tconst url = new URL(req.url)\n\t\tif (url.pathname.endsWith('/presence')) {\n\t\t\treturn Response.json(this.getPresenceMessage().payload)\n\t\t}\n\t\tif (url.pathname.endsWith('/show')) {\n\t\t\tconst users = this.getUsers()\n\t\t\tconst workshopUsers = organizeUsersByWorkshop(users)\n\t\t\treturn new Response(\n\t\t\t\t`\n\t\t\t\t<!DOCTYPE html>\n\t\t\t\t<html lang=\"en\">\n\t\t\t\t<head>\n\t\t\t\t\t<meta charset=\"UTF-8\">\n\t\t\t\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n\t\t\t\t\t<meta http-equiv=\"refresh\" content=\"5\">\n\t\t\t\t\t<title>Epic Web Presence</title>\n\t\t\t\t\t<style>\n\t\t\t\t\t\tbody { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }\n\t\t\t\t\t\th1, h2 { color: #333; }\n\t\t\t\t\t\tul { padding: 0; }\n\t\t\t\t\t\tli { list-style: none; margin-bottom: 10px; }\n\t\t\t\t\t\t.user-avatar { width: 64px; height: 64px; border-radius: 50%; vertical-align: middle; margin-right: 10px; }\n\t\t\t\t\t</style>\n\t\t\t\t</head>\n\t\t\t\t<body>\n\t\t\t\t\t<h1>Epic Web Presence</h1>\n\t\t\t\t\t<p>Total Users: ${users.length}</p>\n\t\t\t\t\t${Object.entries(workshopUsers)\n\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t([workshop, workshopUsers]) => `\n\t\t\t\t\t\t\t<h2>${workshop} (${workshopUsers.length})</h2>\n\t\t\t\t\t\t\t<ul>\n\t\t\t\t\t\t\t\t${workshopUsers.map(generateUserListItem).join('')}\n\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t`,\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.join('')}\n\t\t\t\t</body>\n\t\t\t\t</html>\n\t\t\t\t`,\n\t\t\t\t{\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t'Content-Type': 'text/html',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\t\treturn new Response('not found', { status: 404 })\n\t}\n} satisfies Party.Worker)\n\nfunction shallowMergeConnectionState(\n\tconnection: Party.Connection,\n\tstate: ConnectionState,\n) {\n\tsetConnectionState(connection, (prev) => ({ ...prev, ...state }))\n}\n\nfunction setConnectionState(\n\tconnection: Party.Connection,\n\tstate:\n\t\t| ConnectionState\n\t\t| ((prev: ConnectionState | null) => ConnectionState | null),\n) {\n\tif (typeof state !== 'function') {\n\t\treturn connection.setState(state)\n\t}\n\tconnection.setState((prev: unknown) => {\n\t\tconst prevParseResult = ConnectionStateSchema.safeParse(prev)\n\t\tif (prevParseResult.success) {\n\t\t\treturn state(prevParseResult.data)\n\t\t} else {\n\t\t\treturn state(null)\n\t\t}\n\t})\n}\n\nfunction getConnectionState(connection: Party.Connection) {\n\tconst result = ConnectionStateSchema.safeParse(connection.state)\n\tif (result.success) {\n\t\treturn result.data\n\t} else {\n\t\tsetConnectionState(connection, null)\n\t\treturn null\n\t}\n}\n\nfunction sortUsers(users: Array<User>) {\n\treturn [...users].sort((a, b) => {\n\t\tconst aScore = getScore(a)\n\t\tconst bScore = getScore(b)\n\t\tif (aScore === bScore) return 0\n\t\treturn aScore > bScore ? -1 : 1\n\t})\n}\n\nfunction getScore(user: User) {\n\tlet score = 0\n\tif (user.avatarUrl) score += 1\n\tif (user.avatarUrl?.includes('discordapp')) score += 0.5\n\tif (user.name) score += 1\n\treturn score\n}\n\nfunction organizeUsersByWorkshop(users: Array<User>) {\n\tconst workshopUsers: Record<string, Array<User>> = {}\n\n\tfor (const user of users) {\n\t\tconst workshop = user.location?.workshopTitle ?? 'Unknown Workshop'\n\t\tif (!workshopUsers[workshop]) {\n\t\t\tworkshopUsers[workshop] = []\n\t\t}\n\t\tworkshopUsers[workshop]?.push(user)\n\t}\n\n\t// Sort users within each workshop by exercise and step number\n\tfor (const workshop in workshopUsers) {\n\t\tworkshopUsers[workshop]?.sort((a, b) => {\n\t\t\tconst aExercise = a.location?.exercise?.exerciseNumber ?? 0\n\t\t\tconst bExercise = b.location?.exercise?.exerciseNumber ?? 0\n\t\t\tif (aExercise !== bExercise) return aExercise - bExercise\n\n\t\t\tconst aStep = a.location?.exercise?.stepNumber ?? 0\n\t\t\tconst bStep = b.location?.exercise?.stepNumber ?? 0\n\t\t\treturn aStep - bStep\n\t\t})\n\t}\n\n\treturn workshopUsers\n}\n\nfunction generateUserListItem(user: User) {\n\tconst avatarUrl = user.avatarUrl ?? '/avatar.png'\n\tconst name = user.name ?? 'Anonymous'\n\tconst location = user.location?.exercise\n\t\t? [\n\t\t\t\t`Exercise ${user.location.exercise.exerciseNumber}`,\n\t\t\t\tuser.location.exercise.stepNumber &&\n\t\t\t\t\t`Step ${user.location.exercise.stepNumber}`,\n\t\t\t]\n\t\t\t\t.filter(Boolean)\n\t\t\t\t.join(', ')\n\t\t: user.location?.origin\n\t\t\t? user.location.origin\n\t\t\t: 'Unknown location'\n\n\treturn `\n\t\t<li>\n\t\t\t<img class=\"user-avatar\" src=\"${avatarUrl}\" alt=\"${name}\" />\n\t\t\t<strong>${name}</strong> - ${location}\n\t\t</li>\n\t`\n}\n"]}
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"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","sourcesContent":["import type * as Party from 'partykit/server'\nimport { z } from 'zod'\nimport { UserSchema } from './presence.js'\n\ntype User = z.infer<typeof UserSchema>\nconst ConnectionStateSchema = z\n\t.object({\n\t\tuser: UserSchema.nullable().optional(),\n\t})\n\t.nullable()\n\ntype ConnectionState = z.infer<typeof ConnectionStateSchema>\n\nconst MessageSchema = z\n\t.object({\n\t\ttype: z.literal('remove-user'),\n\t\tpayload: z.object({ id: z.string() }),\n\t})\n\t.or(z.object({ type: z.literal('add-user'), payload: UserSchema }))\n\t.or(\n\t\tz.object({\n\t\t\ttype: z.literal('add-anonymous-user'),\n\t\t\tpayload: z.object({ id: z.string() }),\n\t\t}),\n\t)\n\t.or(\n\t\tz.object({\n\t\t\ttype: z.literal('presence'),\n\t\t\tpayload: z.object({ users: z.array(UserSchema) }),\n\t\t}),\n\t)\ntype Message = z.infer<typeof MessageSchema>\n\nexport default (class Server implements Party.Server {\n\toptions: Party.ServerOptions = {\n\t\thibernate: true,\n\t}\n\n\treadonly party: Party.Room\n\n\tconstructor(party: Party.Room) {\n\t\tthis.party = party\n\t}\n\n\tonClose() {\n\t\tthis.updateUsers()\n\t}\n\n\tonError() {\n\t\tthis.updateUsers()\n\t}\n\n\tupdateUsers() {\n\t\tconst presenceMessage = JSON.stringify(this.getPresenceMessage())\n\t\tfor (const connection of this.party.getConnections()) {\n\t\t\tconnection.send(presenceMessage)\n\t\t}\n\t}\n\n\tgetPresenceMessage() {\n\t\treturn {\n\t\t\ttype: 'presence',\n\t\t\tpayload: { users: this.getUsers() },\n\t\t} satisfies Message\n\t}\n\n\tgetUsers() {\n\t\tconst users = new Map<string, z.infer<typeof UserSchema>>()\n\n\t\tfor (const connection of this.party.getConnections()) {\n\t\t\tconst state = getConnectionState(connection)\n\t\t\tif (state?.user) {\n\t\t\t\tusers.set(state.user.id, state.user)\n\t\t\t}\n\t\t}\n\n\t\treturn sortUsers(Array.from(users.values()))\n\t}\n\n\tonMessage(message: string, sender: Party.Connection) {\n\t\tconst result = MessageSchema.safeParse(JSON.parse(message))\n\t\tif (!result.success) return\n\n\t\tif (result.data.type === 'add-user') {\n\t\t\tshallowMergeConnectionState(sender, { user: result.data.payload })\n\t\t\tthis.updateUsers()\n\t\t} else if (result.data.type === 'remove-user') {\n\t\t\tsetConnectionState(sender, null)\n\t\t\tthis.updateUsers()\n\t\t} else if (result.data.type === 'add-anonymous-user') {\n\t\t\tsetConnectionState(sender, { user: result.data.payload })\n\t\t}\n\t}\n\n\tonRequest(req: Party.Request): Response | Promise<Response> {\n\t\tconst url = new URL(req.url)\n\t\tif (url.pathname.endsWith('/presence')) {\n\t\t\treturn Response.json(this.getPresenceMessage().payload)\n\t\t}\n\t\tif (url.pathname.endsWith('/show')) {\n\t\t\tconst users = this.getUsers()\n\t\t\tconst workshopUsers = organizeUsersByWorkshop(users)\n\t\t\treturn new Response(\n\t\t\t\t`\n\t\t\t\t<!DOCTYPE html>\n\t\t\t\t<html lang=\"en\">\n\t\t\t\t<head>\n\t\t\t\t\t<meta charset=\"UTF-8\">\n\t\t\t\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n\t\t\t\t\t<meta http-equiv=\"refresh\" content=\"5\">\n\t\t\t\t\t<title>Epic Web Presence</title>\n\t\t\t\t\t<style>\n\t\t\t\t\t\tbody { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }\n\t\t\t\t\t\th1, h2 { color: #333; }\n\t\t\t\t\t\tul { padding: 0; }\n\t\t\t\t\t\tli { list-style: none; margin-bottom: 10px; }\n\t\t\t\t\t\t.user-avatar { width: 64px; height: 64px; border-radius: 50%; vertical-align: middle; margin-right: 10px; }\n\t\t\t\t\t</style>\n\t\t\t\t</head>\n\t\t\t\t<body>\n\t\t\t\t\t<h1>Epic Web Presence</h1>\n\t\t\t\t\t<p>Total Users: ${users.length}</p>\n\t\t\t\t\t${Object.entries(workshopUsers)\n\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t([workshop, workshopUsers]) => `\n\t\t\t\t\t\t\t<h2>${workshop} (${workshopUsers.length})</h2>\n\t\t\t\t\t\t\t<ul>\n\t\t\t\t\t\t\t\t${workshopUsers.map(generateUserListItem).join('')}\n\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t`,\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.join('')}\n\t\t\t\t</body>\n\t\t\t\t</html>\n\t\t\t\t`,\n\t\t\t\t{\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t'Content-Type': 'text/html',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\t\treturn new Response('not found', { status: 404 })\n\t}\n} satisfies Party.Worker)\n\nfunction shallowMergeConnectionState(\n\tconnection: Party.Connection,\n\tstate: ConnectionState,\n) {\n\tsetConnectionState(connection, (prev) => ({ ...prev, ...state }))\n}\n\nfunction setConnectionState(\n\tconnection: Party.Connection,\n\tstate:\n\t\t| ConnectionState\n\t\t| ((prev: ConnectionState | null) => ConnectionState | null),\n) {\n\tif (typeof state !== 'function') {\n\t\treturn connection.setState(state)\n\t}\n\tconnection.setState((prev: unknown) => {\n\t\tconst prevParseResult = ConnectionStateSchema.safeParse(prev)\n\t\tif (prevParseResult.success) {\n\t\t\treturn state(prevParseResult.data)\n\t\t} else {\n\t\t\treturn state(null)\n\t\t}\n\t})\n}\n\nfunction getConnectionState(connection: Party.Connection) {\n\tconst result = ConnectionStateSchema.safeParse(connection.state)\n\tif (result.success) {\n\t\treturn result.data\n\t} else {\n\t\tsetConnectionState(connection, null)\n\t\treturn null\n\t}\n}\n\nfunction sortUsers(users: Array<User>) {\n\treturn [...users].sort((a, b) => {\n\t\tconst aScore = getScore(a)\n\t\tconst bScore = getScore(b)\n\t\tif (aScore === bScore) return 0\n\t\treturn aScore > bScore ? -1 : 1\n\t})\n}\n\nfunction getScore(user: User) {\n\tlet score = 0\n\tif (user.avatarUrl) score += 1\n\tif (user.avatarUrl?.includes('discordapp')) score += 0.5\n\tif (user.name) score += 1\n\treturn score\n}\n\nfunction organizeUsersByWorkshop(users: Array<User>) {\n\tconst workshopUsers: Record<string, Array<User>> = {}\n\n\tfor (const user of users) {\n\t\tconst workshop = user.location?.workshopTitle ?? 'Unknown Workshop'\n\t\tif (!workshopUsers[workshop]) {\n\t\t\tworkshopUsers[workshop] = []\n\t\t}\n\t\tworkshopUsers[workshop]?.push(user)\n\t}\n\n\t// Sort users within each workshop by exercise and step number\n\tfor (const workshop in workshopUsers) {\n\t\tworkshopUsers[workshop]?.sort((a, b) => {\n\t\t\tconst aExercise = a.location?.exercise?.exerciseNumber ?? 0\n\t\t\tconst bExercise = b.location?.exercise?.exerciseNumber ?? 0\n\t\t\tif (aExercise !== bExercise) return aExercise - bExercise\n\n\t\t\tconst aStep = a.location?.exercise?.stepNumber ?? 0\n\t\t\tconst bStep = b.location?.exercise?.stepNumber ?? 0\n\t\t\treturn aStep - bStep\n\t\t})\n\t}\n\n\treturn workshopUsers\n}\n\nfunction generateUserListItem(user: User) {\n\tconst avatarUrl = user.avatarUrl ?? '/avatar.png'\n\tconst name = user.name ?? 'Anonymous'\n\tconst location = user.location?.exercise\n\t\t? [\n\t\t\t\t`Exercise ${user.location.exercise.exerciseNumber}`,\n\t\t\t\tuser.location.exercise.stepNumber &&\n\t\t\t\t\t`Step ${user.location.exercise.stepNumber}`,\n\t\t\t]\n\t\t\t\t.filter(Boolean)\n\t\t\t\t.join(', ')\n\t\t: user.location?.origin\n\t\t\t? user.location.origin\n\t\t\t: 'Unknown location'\n\n\tconst accessLabel =\n\t\ttypeof user.hasAccess === 'boolean' ? (user.hasAccess ? '🔑' : '🆓') : ''\n\n\treturn `\n\t\t<li>\n\t\t\t<img class=\"user-avatar\" src=\"${avatarUrl}\" alt=\"${name}\" />\n\t\t\t<strong>${name}</strong> - ${location} ${accessLabel}\n\t\t</li>\n\t`\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@epic-web/workshop-presence",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.3.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"deploy": "partykit deploy"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@epic-web/workshop-utils": "5.
|
|
14
|
+
"@epic-web/workshop-utils": "5.3.0",
|
|
15
15
|
"zod": "^3.23.8"
|
|
16
16
|
},
|
|
17
17
|
"devDependencies": {
|