htmx-router 2.2.5 → 2.2.7
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/event-source.d.ts +22 -1
- package/dist/event-source.js +57 -1
- package/dist/router.d.ts +7 -1
- package/dist/router.js +29 -11
- package/package.json +1 -1
package/dist/event-source.d.ts
CHANGED
|
@@ -34,7 +34,7 @@ export declare class EventSourceSet<JsxEnabled extends boolean = false> extends
|
|
|
34
34
|
* Send update to all EventSources, auto closing failed dispatches
|
|
35
35
|
* @returns number of successful sends
|
|
36
36
|
*/
|
|
37
|
-
dispatch(type: string, data: string): number;
|
|
37
|
+
dispatch(type: string, data: JsxEnabled extends true ? (JSX.Element | string) : string): number;
|
|
38
38
|
/**
|
|
39
39
|
* Cull all closed connections
|
|
40
40
|
* @returns number of connections closed
|
|
@@ -51,6 +51,27 @@ export declare class EventSourceSet<JsxEnabled extends boolean = false> extends
|
|
|
51
51
|
*/
|
|
52
52
|
closeAll(): number;
|
|
53
53
|
}
|
|
54
|
+
export declare class EventSourceMap<T, JsxEnabled extends boolean = false> extends Map<EventSource<JsxEnabled>, T> {
|
|
55
|
+
private onAbort;
|
|
56
|
+
constructor();
|
|
57
|
+
set(stream: EventSource<JsxEnabled>, value: T): this;
|
|
58
|
+
delete(stream: EventSource<JsxEnabled>): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Send update to all EventSources, auto closing failed dispatches
|
|
61
|
+
* @returns number of successful sends
|
|
62
|
+
*/
|
|
63
|
+
dispatch(type: string, data: JsxEnabled extends true ? (JSX.Element | string) : string): number;
|
|
64
|
+
/**
|
|
65
|
+
* Cull all closed connections
|
|
66
|
+
* @returns number of connections closed
|
|
67
|
+
*/
|
|
68
|
+
cull(): number;
|
|
69
|
+
/**
|
|
70
|
+
* Close all connections
|
|
71
|
+
* @returns number of connections closed
|
|
72
|
+
*/
|
|
73
|
+
closeAll(): number;
|
|
74
|
+
}
|
|
54
75
|
type SharedEventSourceCacheRule = {
|
|
55
76
|
limit: number;
|
|
56
77
|
ttl: number;
|
package/dist/event-source.js
CHANGED
|
@@ -182,7 +182,7 @@ export class EventSourceSet extends Set {
|
|
|
182
182
|
if (success)
|
|
183
183
|
count++;
|
|
184
184
|
}
|
|
185
|
-
return count;
|
|
185
|
+
return count - this.size;
|
|
186
186
|
}
|
|
187
187
|
/**
|
|
188
188
|
* Close all connections
|
|
@@ -196,6 +196,62 @@ export class EventSourceSet extends Set {
|
|
|
196
196
|
return count;
|
|
197
197
|
}
|
|
198
198
|
}
|
|
199
|
+
export class EventSourceMap extends Map {
|
|
200
|
+
onAbort;
|
|
201
|
+
constructor() {
|
|
202
|
+
super();
|
|
203
|
+
this.onAbort = () => this.cull();
|
|
204
|
+
}
|
|
205
|
+
set(stream, value) {
|
|
206
|
+
stream._signal.addEventListener('abort', this.onAbort);
|
|
207
|
+
return super.set(stream, value);
|
|
208
|
+
}
|
|
209
|
+
delete(stream) {
|
|
210
|
+
stream._signal.removeEventListener('abort', this.onAbort);
|
|
211
|
+
return super.delete(stream);
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Send update to all EventSources, auto closing failed dispatches
|
|
215
|
+
* @returns number of successful sends
|
|
216
|
+
*/
|
|
217
|
+
dispatch(type, data) {
|
|
218
|
+
let count = 0;
|
|
219
|
+
for (const stream of this.keys()) {
|
|
220
|
+
if (stream.readyState !== EventSource.OPEN)
|
|
221
|
+
continue; // skip closed
|
|
222
|
+
const success = stream.dispatch(type, data);
|
|
223
|
+
if (success)
|
|
224
|
+
count++;
|
|
225
|
+
else
|
|
226
|
+
this.delete(stream);
|
|
227
|
+
}
|
|
228
|
+
return count;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Cull all closed connections
|
|
232
|
+
* @returns number of connections closed
|
|
233
|
+
*/
|
|
234
|
+
cull() {
|
|
235
|
+
const count = this.size;
|
|
236
|
+
for (const stream of this.keys()) {
|
|
237
|
+
if (stream.readyState !== EventSource.CLOSED)
|
|
238
|
+
continue;
|
|
239
|
+
this.delete(stream);
|
|
240
|
+
}
|
|
241
|
+
return count - this.size;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Close all connections
|
|
245
|
+
* @returns number of connections closed
|
|
246
|
+
*/
|
|
247
|
+
closeAll() {
|
|
248
|
+
const count = this.size;
|
|
249
|
+
for (const stream of this.keys())
|
|
250
|
+
stream.close();
|
|
251
|
+
this.clear();
|
|
252
|
+
return count;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
199
255
|
/**
|
|
200
256
|
* DO NOT USE: Experimental
|
|
201
257
|
* @deprecated
|
package/dist/router.d.ts
CHANGED
|
@@ -27,6 +27,11 @@ export declare class RouteResolver {
|
|
|
27
27
|
resolve(): Promise<Response | null>;
|
|
28
28
|
unwind(e: unknown, offset: number): Promise<Response>;
|
|
29
29
|
}
|
|
30
|
+
type IngestContext = {
|
|
31
|
+
path: string[];
|
|
32
|
+
route: string;
|
|
33
|
+
params: string[];
|
|
34
|
+
};
|
|
30
35
|
export declare class RouteTree {
|
|
31
36
|
private nested;
|
|
32
37
|
private index;
|
|
@@ -34,12 +39,13 @@ export declare class RouteTree {
|
|
|
34
39
|
private wild;
|
|
35
40
|
private wildCard;
|
|
36
41
|
constructor();
|
|
37
|
-
ingest(node: RouteLeaf,
|
|
42
|
+
ingest(node: RouteLeaf, ctx?: IngestContext): void;
|
|
38
43
|
_applyChain(out: RouteResolver, fragments: string[], offset?: number): void;
|
|
39
44
|
}
|
|
40
45
|
declare class RouteLeaf {
|
|
41
46
|
readonly module: RouteModule<any>;
|
|
42
47
|
readonly path: string;
|
|
43
48
|
constructor(module: RouteModule<any>, path: string);
|
|
49
|
+
checkParameters(ctx: IngestContext): void;
|
|
44
50
|
}
|
|
45
51
|
export {};
|
package/dist/router.js
CHANGED
|
@@ -148,19 +148,28 @@ export class RouteTree {
|
|
|
148
148
|
this.wild = null;
|
|
149
149
|
this.slug = null;
|
|
150
150
|
}
|
|
151
|
-
ingest(node,
|
|
152
|
-
if (!
|
|
153
|
-
|
|
154
|
-
|
|
151
|
+
ingest(node, ctx) {
|
|
152
|
+
if (!ctx)
|
|
153
|
+
ctx = {
|
|
154
|
+
path: node.path.slice(1).split("/").reverse(),
|
|
155
|
+
route: node.path,
|
|
156
|
+
params: [],
|
|
157
|
+
};
|
|
158
|
+
const segment = ctx.path.pop();
|
|
159
|
+
if (!segment) {
|
|
160
|
+
node.checkParameters(ctx);
|
|
155
161
|
this.index = node;
|
|
156
162
|
return;
|
|
157
163
|
}
|
|
158
|
-
if (
|
|
164
|
+
if (segment === "$") {
|
|
165
|
+
ctx.params.push('$');
|
|
166
|
+
node.checkParameters(ctx);
|
|
159
167
|
this.slug = node;
|
|
160
168
|
return;
|
|
161
169
|
}
|
|
162
|
-
if (
|
|
163
|
-
const wildCard =
|
|
170
|
+
if (segment[0] === "$") {
|
|
171
|
+
const wildCard = segment.slice(1);
|
|
172
|
+
ctx.params.push(wildCard);
|
|
164
173
|
// Check wildcard isn't being changed
|
|
165
174
|
if (!this.wild) {
|
|
166
175
|
this.wildCard = wildCard;
|
|
@@ -169,15 +178,15 @@ export class RouteTree {
|
|
|
169
178
|
else if (wildCard !== this.wildCard) {
|
|
170
179
|
throw new Error(`Redefinition of wild card ${this.wildCard} to ${wildCard}`);
|
|
171
180
|
}
|
|
172
|
-
this.wild.ingest(node,
|
|
181
|
+
this.wild.ingest(node, ctx);
|
|
173
182
|
return;
|
|
174
183
|
}
|
|
175
|
-
let next = this.nested.get(
|
|
184
|
+
let next = this.nested.get(segment);
|
|
176
185
|
if (!next) {
|
|
177
186
|
next = new RouteTree();
|
|
178
|
-
this.nested.set(
|
|
187
|
+
this.nested.set(segment, next);
|
|
179
188
|
}
|
|
180
|
-
next.ingest(node,
|
|
189
|
+
next.ingest(node, ctx);
|
|
181
190
|
}
|
|
182
191
|
_applyChain(out, fragments, offset = 0) {
|
|
183
192
|
if (this.slug) {
|
|
@@ -205,4 +214,13 @@ class RouteLeaf {
|
|
|
205
214
|
this.module = module;
|
|
206
215
|
this.path = path;
|
|
207
216
|
}
|
|
217
|
+
checkParameters(ctx) {
|
|
218
|
+
if (!this.module.parameters)
|
|
219
|
+
return;
|
|
220
|
+
for (const key in this.module.parameters) {
|
|
221
|
+
if (ctx.params.includes(key))
|
|
222
|
+
continue;
|
|
223
|
+
console.warn(`\x1b[33mWarn:\x1b[0m \x1b[36m${ctx.route}\x1b[0m has no parameter \x1b[36m${key}\x1b[0m`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
208
226
|
}
|