@webqit/webflo 0.20.26 → 0.20.28
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/package.json +8 -5
- package/src/build-pi/index.js +6 -4
- package/src/init-pi/index.js +0 -1
- package/src/runtime-pi/{WebfloRuntime.js → AppRuntime.js} +57 -113
- package/src/runtime-pi/webflo-client/DeviceCapabilities.js +1 -1
- package/src/runtime-pi/webflo-client/WebfloClient.js +163 -103
- package/src/runtime-pi/webflo-client/{WebfloRootClient1.js → WebfloRootClientA.js} +39 -56
- package/src/runtime-pi/webflo-client/{WebfloRootClient2.js → WebfloRootClientB.js} +3 -3
- package/src/runtime-pi/webflo-client/WebfloSubClient.js +28 -15
- package/src/runtime-pi/webflo-client/index.js +3 -3
- package/src/runtime-pi/webflo-messaging/ClientPortMixin.js +13 -0
- package/src/runtime-pi/{webflo-server/messaging/ClientRequestRealtime.js → webflo-messaging/ClientRequestPort001.js} +13 -9
- package/src/runtime-pi/webflo-messaging/ClientRequestPort010.js +4 -0
- package/src/runtime-pi/webflo-messaging/ClientRequestPort100.js +17 -0
- package/src/runtime-pi/webflo-messaging/WebfloTenancy001.js +27 -0
- package/src/runtime-pi/webflo-messaging/WebfloTenant001.js +27 -0
- package/src/runtime-pi/webflo-routing/HttpCookies101.js +53 -0
- package/src/runtime-pi/webflo-routing/HttpCookies110.js +3 -0
- package/src/runtime-pi/webflo-routing/{HttpEvent.js → HttpEvent111.js} +95 -73
- package/src/runtime-pi/webflo-routing/HttpKeyvalInterface.js +120 -0
- package/src/runtime-pi/webflo-routing/HttpSession001.js +24 -0
- package/src/runtime-pi/webflo-routing/HttpSession110.js +3 -0
- package/src/runtime-pi/webflo-routing/{HttpThread.js → HttpThread111.js} +54 -13
- package/src/runtime-pi/webflo-routing/{HttpUser.js → HttpUser111.js} +10 -23
- package/src/runtime-pi/webflo-routing/KeyvalsFactory001.js +53 -0
- package/src/runtime-pi/webflo-routing/KeyvalsFactory110.js +48 -0
- package/src/runtime-pi/webflo-routing/KeyvalsFactoryInterface.js +56 -0
- package/src/runtime-pi/webflo-routing/{WebfloRouter.js → WebfloRouter111.js} +5 -6
- package/src/runtime-pi/webflo-server/WebfloServer.js +262 -269
- package/src/runtime-pi/webflo-worker/WebfloWorker.js +97 -44
- package/src/util.js +3 -2
- package/src/runtime-pi/apis.js +0 -9
- package/src/runtime-pi/webflo-client/ClientSideCookies.js +0 -18
- package/src/runtime-pi/webflo-fetch/LiveResponse.js +0 -476
- package/src/runtime-pi/webflo-fetch/index.js +0 -419
- package/src/runtime-pi/webflo-fetch/util.js +0 -28
- package/src/runtime-pi/webflo-messaging/WQBroadcastChannel.js +0 -10
- package/src/runtime-pi/webflo-messaging/WQMessageChannel.js +0 -26
- package/src/runtime-pi/webflo-messaging/WQMessageEvent.js +0 -87
- package/src/runtime-pi/webflo-messaging/WQMessagePort.js +0 -38
- package/src/runtime-pi/webflo-messaging/WQRelayPort.js +0 -47
- package/src/runtime-pi/webflo-messaging/WQSockPort.js +0 -111
- package/src/runtime-pi/webflo-messaging/WQStarPort.js +0 -112
- package/src/runtime-pi/webflo-messaging/wq-message-port.js +0 -413
- package/src/runtime-pi/webflo-routing/HttpCookies.js +0 -43
- package/src/runtime-pi/webflo-routing/HttpSession.js +0 -11
- package/src/runtime-pi/webflo-routing/HttpState.js +0 -182
- package/src/runtime-pi/webflo-server/ServerSideCookies.js +0 -22
- package/src/runtime-pi/webflo-server/ServerSideSession.js +0 -40
- package/src/runtime-pi/webflo-server/messaging/Client.js +0 -27
- package/src/runtime-pi/webflo-server/messaging/Clients.js +0 -25
- package/src/runtime-pi/webflo-url/Url.js +0 -156
- package/src/runtime-pi/webflo-url/index.js +0 -1
- package/src/runtime-pi/webflo-url/urlpattern.js +0 -38
- package/src/runtime-pi/webflo-url/util.js +0 -109
- package/src/runtime-pi/webflo-url/xURL.js +0 -94
- package/src/runtime-pi/webflo-worker/WorkerSideCookies.js +0 -21
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { HttpKeyvalInterface } from './HttpKeyvalInterface.js';
|
|
2
|
+
|
|
3
|
+
export class HttpSession001 extends HttpKeyvalInterface {
|
|
4
|
+
|
|
5
|
+
#sessionID;
|
|
6
|
+
get sessionID() { return this.#sessionID; }
|
|
7
|
+
#ttl;
|
|
8
|
+
|
|
9
|
+
constructor({ context = {}, store, request, thread, sessionID, ttl }) {
|
|
10
|
+
if (!sessionID) {
|
|
11
|
+
throw new Error(`sessionID is required`);
|
|
12
|
+
}
|
|
13
|
+
super({
|
|
14
|
+
context,
|
|
15
|
+
store,
|
|
16
|
+
request,
|
|
17
|
+
thread,
|
|
18
|
+
sessionID,
|
|
19
|
+
ttl
|
|
20
|
+
});
|
|
21
|
+
this.#sessionID = sessionID;
|
|
22
|
+
this.#ttl = ttl;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -1,43 +1,82 @@
|
|
|
1
|
-
|
|
1
|
+
import { KV } from '@webqit/keyval/inmemory';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
export class HttpThread111 {
|
|
4
|
+
|
|
5
|
+
// ------ factory
|
|
6
|
+
|
|
7
|
+
static create({ context = {}, store, threadID, realm = 0 }) {
|
|
8
|
+
let hydrationMode = true;
|
|
4
9
|
if (!threadID || !(new RegExp(`^wq\\.${realm}\\.`)).test(threadID)) {
|
|
5
|
-
threadID = `wq.${realm}.${crypto.randomUUID()}`;
|
|
10
|
+
threadID = `wq.${realm}.${(0 | Math.random() * 9e6).toString(36)}`;//`wq.${realm}.${crypto.randomUUID()}`;
|
|
11
|
+
hydrationMode = false;
|
|
6
12
|
}
|
|
7
|
-
return new this({ store, threadID, realm });
|
|
13
|
+
return new this({ context, store, threadID, realm, lifecycle: { dirty: hydrationMode, extended: false } });
|
|
8
14
|
}
|
|
9
15
|
|
|
16
|
+
// ------
|
|
17
|
+
|
|
18
|
+
#context = {};
|
|
10
19
|
#store;
|
|
11
20
|
#threadID;
|
|
12
21
|
#realm;
|
|
13
|
-
#
|
|
22
|
+
#lifecycle;
|
|
14
23
|
|
|
15
24
|
get threadID() { return this.#threadID; }
|
|
25
|
+
get dirty() { return !!this.#lifecycle.dirty; }
|
|
26
|
+
get extended() { return !!this.#lifecycle.extended; }
|
|
16
27
|
|
|
17
|
-
|
|
18
|
-
|
|
28
|
+
get _context() { return this.#context; }
|
|
29
|
+
get _parentEvent() { return this.#context?.parentEvent; }
|
|
30
|
+
|
|
31
|
+
constructor({ context = {}, store, threadID, realm = 0, lifecycle = { dirty: false, extended: false } }) {
|
|
32
|
+
if (!(store instanceof KV)) {
|
|
33
|
+
throw new Error('HttpKeyval expects a valid store instance!');
|
|
34
|
+
}
|
|
35
|
+
if (context) Object.assign(this.#context, context);
|
|
36
|
+
this.#store = store;
|
|
19
37
|
this.#threadID = threadID;
|
|
20
38
|
this.#realm = realm;
|
|
39
|
+
this.#lifecycle = lifecycle;
|
|
21
40
|
}
|
|
22
41
|
|
|
23
|
-
|
|
42
|
+
// ------ lifecycle
|
|
43
|
+
|
|
44
|
+
extend(set = true) { this.#lifecycle.extended = !!set; }
|
|
24
45
|
|
|
25
|
-
|
|
46
|
+
clone() {
|
|
47
|
+
return new this.constructor({
|
|
48
|
+
context: this.#context,
|
|
49
|
+
store: this.#store,
|
|
50
|
+
threadID: this.#threadID,
|
|
51
|
+
realm: this.#realm,
|
|
52
|
+
lifecycle: this.#lifecycle,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
26
55
|
|
|
27
|
-
spawn(
|
|
56
|
+
spawn(threadID = null) {
|
|
28
57
|
return this.constructor.create({
|
|
58
|
+
context: this.#context,
|
|
29
59
|
store: this.#store,
|
|
30
|
-
threadID:
|
|
60
|
+
threadID: threadID,
|
|
31
61
|
realm: this.#realm
|
|
32
62
|
});
|
|
33
63
|
}
|
|
34
64
|
|
|
65
|
+
async _cleanup() {
|
|
66
|
+
if (this.#lifecycle.extended) return;
|
|
67
|
+
await this.clear();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// ------ standard methods
|
|
71
|
+
|
|
35
72
|
async keys() {
|
|
73
|
+
if (!this.#lifecycle.dirty) return [];
|
|
36
74
|
const thread = await this.#store.get(this.#threadID) || {};
|
|
37
75
|
return Object.keys(thread);
|
|
38
76
|
}
|
|
39
77
|
|
|
40
78
|
async has(key, filter = null) {
|
|
79
|
+
if (!this.#lifecycle.dirty) return false;
|
|
41
80
|
if (filter === true || !filter) return (await this.keys()).includes(key);
|
|
42
81
|
const thread = await this.#store.get(this.#threadID) || {};
|
|
43
82
|
const values = [].concat(thread[key] ?? []);
|
|
@@ -45,14 +84,15 @@ export class HttpThread {
|
|
|
45
84
|
}
|
|
46
85
|
|
|
47
86
|
async append(key, value) {
|
|
87
|
+
this.#lifecycle.dirty = true;
|
|
48
88
|
const thread = await this.#store.get(this.#threadID) || {};
|
|
49
89
|
thread[key] = [].concat(thread[key] ?? []);
|
|
50
90
|
thread[key].push(value);
|
|
51
91
|
await this.#store.set(this.#threadID, thread);
|
|
52
|
-
return this;
|
|
53
92
|
}
|
|
54
93
|
|
|
55
94
|
async get(key, filter = null) {
|
|
95
|
+
if (!this.#lifecycle.dirty) return filter === true ? [] : undefined;
|
|
56
96
|
const thread = await this.#store.get(this.#threadID) || {};
|
|
57
97
|
const values = [].concat(thread[key] ?? []);
|
|
58
98
|
|
|
@@ -67,6 +107,7 @@ export class HttpThread {
|
|
|
67
107
|
}
|
|
68
108
|
|
|
69
109
|
async consume(key, filter = null) {
|
|
110
|
+
if (!this.#lifecycle.dirty) return filter === true ? [] : undefined;
|
|
70
111
|
const thread = await this.#store.get(this.#threadID) || {};
|
|
71
112
|
const values = [].concat(thread[key] ?? []);
|
|
72
113
|
|
|
@@ -94,7 +135,7 @@ export class HttpThread {
|
|
|
94
135
|
}
|
|
95
136
|
|
|
96
137
|
async clear() {
|
|
138
|
+
if (!this.#lifecycle.dirty) return;
|
|
97
139
|
await this.#store.delete(this.#threadID);
|
|
98
|
-
return this;
|
|
99
140
|
}
|
|
100
141
|
}
|
|
@@ -1,21 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { HttpKeyvalInterface } from './HttpKeyvalInterface.js';
|
|
2
2
|
|
|
3
|
-
export class
|
|
3
|
+
export class HttpUser111 extends HttpKeyvalInterface {
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
return new this({ store, request, thread, client });
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
#client;
|
|
10
|
-
|
|
11
|
-
constructor({ store, request, thread, client }) {
|
|
12
|
-
super({
|
|
13
|
-
store,
|
|
14
|
-
request,
|
|
15
|
-
thread
|
|
16
|
-
});
|
|
17
|
-
this.#client = client;
|
|
18
|
-
}
|
|
5
|
+
get _client() { return this._parentEvent.client; }
|
|
19
6
|
|
|
20
7
|
async isSignedIn(callback = null, options = {}) {
|
|
21
8
|
const isSignedIn = await this.get('id');
|
|
@@ -23,7 +10,7 @@ export class HttpUser extends HttpState {
|
|
|
23
10
|
await callback(isSignedIn);
|
|
24
11
|
return options.once
|
|
25
12
|
? undefined
|
|
26
|
-
: this.
|
|
13
|
+
: this.subscribe('id', callback, options);
|
|
27
14
|
}
|
|
28
15
|
return !!isSignedIn;
|
|
29
16
|
}
|
|
@@ -41,20 +28,20 @@ export class HttpUser extends HttpState {
|
|
|
41
28
|
|
|
42
29
|
async confirm(data, callback, options = {}) {
|
|
43
30
|
return await new Promise((resolve) => {
|
|
44
|
-
this
|
|
31
|
+
this._client.postRequest(
|
|
45
32
|
data,
|
|
46
|
-
(event) => resolve(callback ? callback(event) : event),
|
|
47
|
-
{ ...options,
|
|
33
|
+
(event) => resolve(callback ? callback(event.data) : event.data),
|
|
34
|
+
{ ...options, type: 'confirm' }
|
|
48
35
|
);
|
|
49
36
|
});
|
|
50
37
|
}
|
|
51
38
|
|
|
52
39
|
async prompt(data, callback, options = {}) {
|
|
53
40
|
return await new Promise((resolve) => {
|
|
54
|
-
this
|
|
41
|
+
this._client.postRequest(
|
|
55
42
|
data,
|
|
56
|
-
(event) => resolve(callback ? callback(event) : event),
|
|
57
|
-
{ ...options,
|
|
43
|
+
(event) => resolve(callback ? callback(event.data) : event.data),
|
|
44
|
+
{ ...options, type: 'prompt' }
|
|
58
45
|
);
|
|
59
46
|
});
|
|
60
47
|
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { KeyvalsFactoryInterface } from './KeyvalsFactoryInterface.js';
|
|
2
|
+
import { RedisKV, createClient } from '@webqit/keyval/redis';
|
|
3
|
+
import { InMemoryKV } from '@webqit/keyval/inmemory';
|
|
4
|
+
import { FileKV } from '@webqit/keyval/file';
|
|
5
|
+
|
|
6
|
+
export class KeyvalsFactory001 extends KeyvalsFactoryInterface {
|
|
7
|
+
|
|
8
|
+
#redisNamespace;
|
|
9
|
+
#redisChannel;
|
|
10
|
+
#redisUrl;
|
|
11
|
+
#localDir;
|
|
12
|
+
|
|
13
|
+
constructor({ localDir = null, redisUrl = null, redisNamespace = '*', redisChannel = null, } = {}) {
|
|
14
|
+
super();
|
|
15
|
+
this.#localDir = localDir;
|
|
16
|
+
this.#redisUrl = redisUrl;
|
|
17
|
+
this.#redisNamespace = redisNamespace;
|
|
18
|
+
this.#redisChannel = redisChannel ?? `__webflo_app__@${this.#redisNamespace}`;
|
|
19
|
+
|
|
20
|
+
// Set up Redis watch
|
|
21
|
+
if (this.#redisUrl && this.#redisChannel) {
|
|
22
|
+
const watchClient = createClient({ url: this.#redisUrl });
|
|
23
|
+
watchClient.connect().then(() => {
|
|
24
|
+
watchClient.subscribe(this.#redisChannel, async (message) => {
|
|
25
|
+
try {
|
|
26
|
+
const event = JSON.parse(message?.trim());
|
|
27
|
+
if (!Array.isArray(event?.origins)
|
|
28
|
+
|| event.origins[1] === this.instanceID) return;
|
|
29
|
+
await this.kvHandle._fire(event);
|
|
30
|
+
} catch (e) {
|
|
31
|
+
console.error('Failed to parse message JSON:', message);
|
|
32
|
+
console.error(e, '\n\n');
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
create({ type, ...options }) {
|
|
40
|
+
const { path, ttl = 0 } = options;
|
|
41
|
+
|
|
42
|
+
if (!Array.isArray(path) || path.length !== 2) throw new Error('Path must be an array of length 2');
|
|
43
|
+
if (options.origins && (!Array.isArray(options.origins) || options.origins.length !== 1)) throw new Error('Origins must be an array of length 1');
|
|
44
|
+
if (ttl && typeof ttl !== 'number') throw new Error('TTL must be a number');
|
|
45
|
+
|
|
46
|
+
const origins = (options.origins || this.defaultOrigins).concat(this.instanceID);
|
|
47
|
+
|
|
48
|
+
if (type === 'redis' || !type && this.#redisUrl) return RedisKV.create({ path, ttl, redisUrl: this.#redisUrl, channel: this.#redisChannel, namespace: this.#redisNamespace, registry: this.registry, origins });
|
|
49
|
+
if (type === 'file' || !type && this.#localDir) return FileKV.create({ path, ttl, dir: this.#localDir, registry: this.registry, origins });
|
|
50
|
+
if (type === 'inmemory' || !type) return InMemoryKV.create({ path, ttl, registry: this.registry, origins });
|
|
51
|
+
throw new Error(`Invalid type: ${type}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { KeyvalsFactoryInterface } from './KeyvalsFactoryInterface.js';
|
|
2
|
+
import { IndexedDBKV } from '@webqit/keyval/indexeddb';
|
|
3
|
+
import { CookieStoreKV } from '@webqit/keyval/cookiestore';
|
|
4
|
+
import { InMemoryKV } from '@webqit/keyval/inmemory';
|
|
5
|
+
|
|
6
|
+
export class KeyvalsFactory110 extends KeyvalsFactoryInterface {
|
|
7
|
+
|
|
8
|
+
#dbName;
|
|
9
|
+
#channel;
|
|
10
|
+
#cookiePath;
|
|
11
|
+
|
|
12
|
+
constructor({ dbName = 'webflo_keyval', cookiePath = '/', channel = '__webflo_app__' } = {}) {
|
|
13
|
+
super();
|
|
14
|
+
this.#dbName = dbName;
|
|
15
|
+
this.#cookiePath = cookiePath;
|
|
16
|
+
this.#channel = channel;
|
|
17
|
+
|
|
18
|
+
// Set up Redis watch
|
|
19
|
+
if (this.#channel) {
|
|
20
|
+
const watchClient = new BroadcastChannel(this.#channel);
|
|
21
|
+
watchClient.onmessage = async (message) => {
|
|
22
|
+
try {
|
|
23
|
+
const event = message.data;
|
|
24
|
+
if (!Array.isArray(event?.origins)
|
|
25
|
+
|| event.origins[1] === this.instanceID) return;
|
|
26
|
+
await this.kvHandle._fire(event);
|
|
27
|
+
} catch (e) {
|
|
28
|
+
console.error('Failed to parse message JSON:', message);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
create({ type = 'indexeddb', ...options }) {
|
|
35
|
+
const { path, ttl = 0 } = options;
|
|
36
|
+
|
|
37
|
+
if (!Array.isArray(path) || path.length !== 2) throw new Error('Path must be an array of length 2');
|
|
38
|
+
if (options.origins && (!Array.isArray(options.origins) || options.origins.length !== 1)) throw new Error('Origins must be an array of length 1');
|
|
39
|
+
if (ttl && typeof ttl !== 'number') throw new Error('TTL must be a number');
|
|
40
|
+
|
|
41
|
+
const origins = (options.origins || this.defaultOrigins).concat(this.instanceID);
|
|
42
|
+
|
|
43
|
+
if (type === 'indexeddb') return IndexedDBKV.create({ dbName: this.#dbName, path, ttl, channel: this.#channel, registry: this.registry, origins });
|
|
44
|
+
if (type === 'cookiestore') return CookieStoreKV.create({ path, ttl, cookiePath: this.#cookiePath, registry: this.registry, origins });
|
|
45
|
+
if (type === 'inmemory') return InMemoryKV.create({ path, ttl, registry: this.registry, origins });
|
|
46
|
+
throw new Error(`Invalid type: ${type}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { KV } from '@webqit/keyval/inmemory';
|
|
2
|
+
|
|
3
|
+
export class KeyvalsFactoryInterface {
|
|
4
|
+
|
|
5
|
+
#instanceID = (0 | Math.random() * 9e6).toString(36);
|
|
6
|
+
#registry = new Map;
|
|
7
|
+
#defaultOrigins = ['*'/* requestID */];
|
|
8
|
+
#kvHandle;
|
|
9
|
+
|
|
10
|
+
get instanceID() { return this.#instanceID; }
|
|
11
|
+
get registry() { return this.#registry; }
|
|
12
|
+
get defaultOrigins() { return this.#defaultOrigins; }
|
|
13
|
+
get kvHandle() { return this.#kvHandle; }
|
|
14
|
+
|
|
15
|
+
constructor() {
|
|
16
|
+
this.#kvHandle = KV.create({ path: [], registry: this.#registry, origins: this.#defaultOrigins.concat(this.#instanceID) });
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
subscribe(kvKey, callback, { scope = 1, ...options } = {}) {
|
|
20
|
+
if (!kvKey) throw new Error('kvKey must be specified');
|
|
21
|
+
return this.#kvHandle.subscribe(kvKey, callback, { scope, ...options });
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
#handlers = new Map;
|
|
25
|
+
|
|
26
|
+
defineHandler(kvKey, key, ...handlers) {
|
|
27
|
+
const $handlers = [];
|
|
28
|
+
for (let handler of handlers) {
|
|
29
|
+
if (typeof handler === 'function') {
|
|
30
|
+
handler = { callback: handler };
|
|
31
|
+
} else if (typeof handler === 'string') {
|
|
32
|
+
handler = { url: handler };
|
|
33
|
+
} else if (!(typeof handler === 'object' && handler && (handler = { ...handler }))
|
|
34
|
+
|| typeof handler.callback !== 'function' && typeof handler.url !== 'string') {
|
|
35
|
+
throw new Error(`Handler must be either an URL or a function or an object specifying either an URL (handler.url) or a function (handler.callback)`);
|
|
36
|
+
}
|
|
37
|
+
if (typeof handler.with === 'object' && handler.with) {
|
|
38
|
+
handler.with = { ...handler.with };
|
|
39
|
+
} else if (handler.with) {
|
|
40
|
+
throw new Error(`The "with" parameter must be a valid JSON object`);
|
|
41
|
+
}
|
|
42
|
+
$handlers.push(handler);
|
|
43
|
+
}
|
|
44
|
+
if (!this.#handlers.has(kvKey)) {
|
|
45
|
+
this.#handlers.set(kvKey, new Map);
|
|
46
|
+
}
|
|
47
|
+
this.#handlers.get(kvKey).set(key, $handlers);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
getHandlers(kvKey, autoCreate = false) {
|
|
51
|
+
if (!this.#handlers.has(kvKey) && autoCreate) {
|
|
52
|
+
this.#handlers.set(kvKey, new Map);
|
|
53
|
+
}
|
|
54
|
+
return this.#handlers.get(kvKey);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { _isFunction, _isArray, _isObject } from '@webqit/util/js/index.js';
|
|
2
2
|
import { _from as _arrFrom } from '@webqit/util/arr/index.js';
|
|
3
|
-
import { LiveResponse } from '
|
|
4
|
-
import {
|
|
5
|
-
import { path as Path } from '../webflo-url/util.js';
|
|
3
|
+
import { LiveResponse, RequestPlus } from '@webqit/fetch-plus';
|
|
4
|
+
import { Path } from '@webqit/url-plus';
|
|
6
5
|
|
|
7
|
-
export class
|
|
6
|
+
export class WebfloRouter111 {
|
|
8
7
|
|
|
9
8
|
#runtime;
|
|
10
9
|
#path;
|
|
@@ -103,7 +102,7 @@ export class WebfloRouter {
|
|
|
103
102
|
// Build request inheritance chain
|
|
104
103
|
const requestInheritanceChain = [url];
|
|
105
104
|
if (!isFetch && thisTick.event.request instanceof Request) {
|
|
106
|
-
const { url: _, ...init } = await
|
|
105
|
+
const { url: _, ...init } = await RequestPlus.copy(thisTick.event.request);
|
|
107
106
|
requestInheritanceChain.push(init);
|
|
108
107
|
}
|
|
109
108
|
const noArg2 = () => {
|
|
@@ -111,7 +110,7 @@ export class WebfloRouter {
|
|
|
111
110
|
};
|
|
112
111
|
if (args[0] instanceof Request) {
|
|
113
112
|
if (args[1]) noArg2();
|
|
114
|
-
const { url: _, ...init } = await
|
|
113
|
+
const { url: _, ...init } = await RequestPlus.copy(args[0]);
|
|
115
114
|
requestInheritanceChain.push(init);
|
|
116
115
|
} else if (!isFetch && _isObject(args[0])) {
|
|
117
116
|
if (args[1]) noArg2();
|