@remix-run/router 1.2.1 → 1.3.0-pre.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/CHANGELOG.md +12 -0
- package/dist/history.d.ts +6 -1
- package/dist/index.d.ts +1 -2
- package/dist/router.cjs.js +164 -83
- package/dist/router.cjs.js.map +1 -1
- package/dist/router.d.ts +2 -0
- package/dist/router.js +163 -84
- package/dist/router.js.map +1 -1
- package/dist/router.umd.js +164 -83
- package/dist/router.umd.js.map +1 -1
- package/dist/router.umd.min.js +2 -2
- package/dist/router.umd.min.js.map +1 -1
- package/dist/utils.d.ts +14 -7
- package/history.ts +33 -23
- package/index.ts +3 -3
- package/package.json +1 -1
- package/router.ts +77 -34
- package/utils.ts +88 -42
package/utils.ts
CHANGED
|
@@ -31,6 +31,8 @@ export interface SuccessResult {
|
|
|
31
31
|
export interface DeferredResult {
|
|
32
32
|
type: ResultType.deferred;
|
|
33
33
|
deferredData: DeferredData;
|
|
34
|
+
statusCode?: number;
|
|
35
|
+
headers?: Headers;
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
/**
|
|
@@ -198,7 +200,9 @@ type _PathParam<Path extends string> =
|
|
|
198
200
|
? _PathParam<L> | _PathParam<R>
|
|
199
201
|
: // find params after `:`
|
|
200
202
|
Path extends `:${infer Param}`
|
|
201
|
-
? Param
|
|
203
|
+
? Param extends `${infer Optional}?`
|
|
204
|
+
? Optional
|
|
205
|
+
: Param
|
|
202
206
|
: // otherwise, there aren't any params present
|
|
203
207
|
never;
|
|
204
208
|
|
|
@@ -614,7 +618,7 @@ function matchRouteBranch<
|
|
|
614
618
|
export function generatePath<Path extends string>(
|
|
615
619
|
originalPath: Path,
|
|
616
620
|
params: {
|
|
617
|
-
[key in PathParam<Path>]: string;
|
|
621
|
+
[key in PathParam<Path>]: string | null;
|
|
618
622
|
} = {} as any
|
|
619
623
|
): string {
|
|
620
624
|
let path = originalPath;
|
|
@@ -629,27 +633,49 @@ export function generatePath<Path extends string>(
|
|
|
629
633
|
path = path.replace(/\*$/, "/*") as Path;
|
|
630
634
|
}
|
|
631
635
|
|
|
632
|
-
return
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
636
|
+
return (
|
|
637
|
+
path
|
|
638
|
+
.replace(
|
|
639
|
+
/^:(\w+)(\??)/g,
|
|
640
|
+
(_, key: PathParam<Path>, optional: string | undefined) => {
|
|
641
|
+
let param = params[key];
|
|
642
|
+
if (optional === "?") {
|
|
643
|
+
return param == null ? "" : param;
|
|
644
|
+
}
|
|
645
|
+
if (param == null) {
|
|
646
|
+
invariant(false, `Missing ":${key}" param`);
|
|
647
|
+
}
|
|
648
|
+
return param;
|
|
649
|
+
}
|
|
650
|
+
)
|
|
651
|
+
.replace(
|
|
652
|
+
/\/:(\w+)(\??)/g,
|
|
653
|
+
(_, key: PathParam<Path>, optional: string | undefined) => {
|
|
654
|
+
let param = params[key];
|
|
655
|
+
if (optional === "?") {
|
|
656
|
+
return param == null ? "" : `/${param}`;
|
|
657
|
+
}
|
|
658
|
+
if (param == null) {
|
|
659
|
+
invariant(false, `Missing ":${key}" param`);
|
|
660
|
+
}
|
|
661
|
+
return `/${param}`;
|
|
662
|
+
}
|
|
663
|
+
)
|
|
664
|
+
// Remove any optional markers from optional static segments
|
|
665
|
+
.replace(/\?/g, "")
|
|
666
|
+
.replace(/(\/?)\*/, (_, prefix, __, str) => {
|
|
667
|
+
const star = "*" as PathParam<Path>;
|
|
668
|
+
|
|
669
|
+
if (params[star] == null) {
|
|
670
|
+
// If no splat was provided, trim the trailing slash _unless_ it's
|
|
671
|
+
// the entire path
|
|
672
|
+
return str === "/*" ? "/" : "";
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
// Apply the splat
|
|
676
|
+
return `${prefix}${params[star]}`;
|
|
677
|
+
})
|
|
678
|
+
);
|
|
653
679
|
}
|
|
654
680
|
|
|
655
681
|
/**
|
|
@@ -1131,14 +1157,17 @@ export interface TrackedPromise extends Promise<any> {
|
|
|
1131
1157
|
export class AbortedDeferredError extends Error {}
|
|
1132
1158
|
|
|
1133
1159
|
export class DeferredData {
|
|
1134
|
-
private
|
|
1160
|
+
private pendingKeysSet: Set<string> = new Set<string>();
|
|
1135
1161
|
private controller: AbortController;
|
|
1136
1162
|
private abortPromise: Promise<void>;
|
|
1137
1163
|
private unlistenAbortSignal: () => void;
|
|
1138
|
-
private
|
|
1164
|
+
private subscribers: Set<(aborted: boolean, settledKey?: string) => void> =
|
|
1165
|
+
new Set();
|
|
1139
1166
|
data: Record<string, unknown>;
|
|
1167
|
+
init?: ResponseInit;
|
|
1168
|
+
deferredKeys: string[] = [];
|
|
1140
1169
|
|
|
1141
|
-
constructor(data: Record<string, unknown
|
|
1170
|
+
constructor(data: Record<string, unknown>, responseInit?: ResponseInit) {
|
|
1142
1171
|
invariant(
|
|
1143
1172
|
data && typeof data === "object" && !Array.isArray(data),
|
|
1144
1173
|
"defer() only accepts plain objects"
|
|
@@ -1162,17 +1191,20 @@ export class DeferredData {
|
|
|
1162
1191
|
}),
|
|
1163
1192
|
{}
|
|
1164
1193
|
);
|
|
1194
|
+
|
|
1195
|
+
this.init = responseInit;
|
|
1165
1196
|
}
|
|
1166
1197
|
|
|
1167
1198
|
private trackPromise(
|
|
1168
|
-
key: string
|
|
1199
|
+
key: string,
|
|
1169
1200
|
value: Promise<unknown> | unknown
|
|
1170
1201
|
): TrackedPromise | unknown {
|
|
1171
1202
|
if (!(value instanceof Promise)) {
|
|
1172
1203
|
return value;
|
|
1173
1204
|
}
|
|
1174
1205
|
|
|
1175
|
-
this.
|
|
1206
|
+
this.deferredKeys.push(key);
|
|
1207
|
+
this.pendingKeysSet.add(key);
|
|
1176
1208
|
|
|
1177
1209
|
// We store a little wrapper promise that will be extended with
|
|
1178
1210
|
// _data/_error props upon resolve/reject
|
|
@@ -1191,7 +1223,7 @@ export class DeferredData {
|
|
|
1191
1223
|
|
|
1192
1224
|
private onSettle(
|
|
1193
1225
|
promise: TrackedPromise,
|
|
1194
|
-
key: string
|
|
1226
|
+
key: string,
|
|
1195
1227
|
error: unknown,
|
|
1196
1228
|
data?: unknown
|
|
1197
1229
|
): unknown {
|
|
@@ -1204,34 +1236,37 @@ export class DeferredData {
|
|
|
1204
1236
|
return Promise.reject(error);
|
|
1205
1237
|
}
|
|
1206
1238
|
|
|
1207
|
-
this.
|
|
1239
|
+
this.pendingKeysSet.delete(key);
|
|
1208
1240
|
|
|
1209
1241
|
if (this.done) {
|
|
1210
1242
|
// Nothing left to abort!
|
|
1211
1243
|
this.unlistenAbortSignal();
|
|
1212
1244
|
}
|
|
1213
1245
|
|
|
1214
|
-
const subscriber = this.subscriber;
|
|
1215
1246
|
if (error) {
|
|
1216
1247
|
Object.defineProperty(promise, "_error", { get: () => error });
|
|
1217
|
-
|
|
1248
|
+
this.emit(false, key);
|
|
1218
1249
|
return Promise.reject(error);
|
|
1219
1250
|
}
|
|
1220
1251
|
|
|
1221
1252
|
Object.defineProperty(promise, "_data", { get: () => data });
|
|
1222
|
-
|
|
1253
|
+
this.emit(false, key);
|
|
1223
1254
|
return data;
|
|
1224
1255
|
}
|
|
1225
1256
|
|
|
1226
|
-
|
|
1227
|
-
this.subscriber
|
|
1257
|
+
private emit(aborted: boolean, settledKey?: string) {
|
|
1258
|
+
this.subscribers.forEach((subscriber) => subscriber(aborted, settledKey));
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
subscribe(fn: (aborted: boolean, settledKey?: string) => void) {
|
|
1262
|
+
this.subscribers.add(fn);
|
|
1263
|
+
return () => this.subscribers.delete(fn);
|
|
1228
1264
|
}
|
|
1229
1265
|
|
|
1230
1266
|
cancel() {
|
|
1231
1267
|
this.controller.abort();
|
|
1232
|
-
this.
|
|
1233
|
-
|
|
1234
|
-
subscriber && subscriber(true);
|
|
1268
|
+
this.pendingKeysSet.forEach((v, k) => this.pendingKeysSet.delete(k));
|
|
1269
|
+
this.emit(true);
|
|
1235
1270
|
}
|
|
1236
1271
|
|
|
1237
1272
|
async resolveData(signal: AbortSignal) {
|
|
@@ -1252,7 +1287,7 @@ export class DeferredData {
|
|
|
1252
1287
|
}
|
|
1253
1288
|
|
|
1254
1289
|
get done() {
|
|
1255
|
-
return this.
|
|
1290
|
+
return this.pendingKeysSet.size === 0;
|
|
1256
1291
|
}
|
|
1257
1292
|
|
|
1258
1293
|
get unwrappedData() {
|
|
@@ -1269,6 +1304,10 @@ export class DeferredData {
|
|
|
1269
1304
|
{}
|
|
1270
1305
|
);
|
|
1271
1306
|
}
|
|
1307
|
+
|
|
1308
|
+
get pendingKeys() {
|
|
1309
|
+
return Array.from(this.pendingKeysSet);
|
|
1310
|
+
}
|
|
1272
1311
|
}
|
|
1273
1312
|
|
|
1274
1313
|
function isTrackedPromise(value: any): value is TrackedPromise {
|
|
@@ -1288,9 +1327,16 @@ function unwrapTrackedPromise(value: any) {
|
|
|
1288
1327
|
return value._data;
|
|
1289
1328
|
}
|
|
1290
1329
|
|
|
1291
|
-
export
|
|
1292
|
-
|
|
1293
|
-
|
|
1330
|
+
export type DeferFunction = (
|
|
1331
|
+
data: Record<string, unknown>,
|
|
1332
|
+
init?: number | ResponseInit
|
|
1333
|
+
) => DeferredData;
|
|
1334
|
+
|
|
1335
|
+
export const defer: DeferFunction = (data, init = {}) => {
|
|
1336
|
+
let responseInit = typeof init === "number" ? { status: init } : init;
|
|
1337
|
+
|
|
1338
|
+
return new DeferredData(data, responseInit);
|
|
1339
|
+
};
|
|
1294
1340
|
|
|
1295
1341
|
export type RedirectFunction = (
|
|
1296
1342
|
url: string,
|