@party-stack/web-runtime 0.3.7 → 0.4.1
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/lib/NavigatorNetworkConnectivity.d.ts +13 -11
- package/lib/NavigatorNetworkConnectivity.d.ts.map +1 -1
- package/lib/NavigatorNetworkConnectivity.js +62 -69
- package/lib/NavigatorNetworkConnectivity.js.map +1 -1
- package/lib/OPFSBlobBytesStore.d.ts +10 -8
- package/lib/OPFSBlobBytesStore.d.ts.map +1 -1
- package/lib/OPFSBlobBytesStore.js +43 -56
- package/lib/OPFSBlobBytesStore.js.map +1 -1
- package/lib/createWebBrowserAuthentication.d.ts +5 -3
- package/lib/createWebBrowserAuthentication.d.ts.map +1 -1
- package/lib/createWebBrowserAuthentication.js +60 -73
- package/lib/createWebBrowserAuthentication.js.map +1 -1
- package/lib/createWebRuntime.d.ts +4 -1
- package/lib/createWebRuntime.d.ts.map +1 -1
- package/lib/createWebRuntime.js +37 -44
- package/lib/createWebRuntime.js.map +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.js +2 -2
- package/package.json +15 -14
- package/lib/NavigatorNetworkConnectivity.test.d.ts +0 -2
- package/lib/NavigatorNetworkConnectivity.test.d.ts.map +0 -1
- package/lib/NavigatorNetworkConnectivity.test.js +0 -51
- package/lib/NavigatorNetworkConnectivity.test.js.map +0 -1
- package/lib/createWebBrowserAuthentication.test.d.ts +0 -2
- package/lib/createWebBrowserAuthentication.test.d.ts.map +0 -1
- package/lib/createWebBrowserAuthentication.test.js +0 -71
- package/lib/createWebBrowserAuthentication.test.js.map +0 -1
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js.map +0 -1
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { NetworkConnectivity } from "@party-stack/runtime";
|
|
2
|
+
//#region src/NavigatorNetworkConnectivity.d.ts
|
|
2
3
|
export declare class NavigatorNetworkConnectivity implements NetworkConnectivity {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
4
|
+
private readonly listeners;
|
|
5
|
+
private lifetime;
|
|
6
|
+
private connected;
|
|
7
|
+
private closePromise;
|
|
8
|
+
private constructor();
|
|
9
|
+
static create(): NavigatorNetworkConnectivity;
|
|
10
|
+
get isConnected(): boolean;
|
|
11
|
+
subscribe(listener: (isConnected: boolean) => void): () => void;
|
|
12
|
+
close(): Promise<void>;
|
|
13
|
+
private setConnected;
|
|
13
14
|
}
|
|
15
|
+
//#endregion
|
|
14
16
|
//# sourceMappingURL=NavigatorNetworkConnectivity.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NavigatorNetworkConnectivity.d.ts","
|
|
1
|
+
{"version":3,"file":"NavigatorNetworkConnectivity.d.ts","names":[],"sources":["../src/NavigatorNetworkConnectivity.ts"],"mappings":";;qBAKa,wCAAwC;mBAChC;UACT;UACA;UACA;UAED;SAIA,UAAU;MAqCb;EAIJ,UAAU,WAAW;EAOrB,SAAS;UAOD"}
|
|
@@ -1,71 +1,64 @@
|
|
|
1
1
|
import { once, race, run, sleep } from "effection";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
return;
|
|
65
|
-
this.connected = isConnected;
|
|
66
|
-
for (const listener of this.listeners) {
|
|
67
|
-
listener(isConnected);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
2
|
+
//#region src/NavigatorNetworkConnectivity.ts
|
|
3
|
+
const ONLINE_STABILIZATION_MS = 1e3;
|
|
4
|
+
var NavigatorNetworkConnectivity = class NavigatorNetworkConnectivity {
|
|
5
|
+
listeners = /* @__PURE__ */ new Set();
|
|
6
|
+
lifetime;
|
|
7
|
+
connected;
|
|
8
|
+
closePromise;
|
|
9
|
+
constructor(initiallyConnected) {
|
|
10
|
+
this.connected = initiallyConnected;
|
|
11
|
+
}
|
|
12
|
+
static create() {
|
|
13
|
+
const connectivity = new NavigatorNetworkConnectivity(navigator.onLine);
|
|
14
|
+
connectivity.lifetime = run(function* () {
|
|
15
|
+
while (true) {
|
|
16
|
+
if (!(yield* race([(function* () {
|
|
17
|
+
yield* once(window, "online");
|
|
18
|
+
return true;
|
|
19
|
+
})(), (function* () {
|
|
20
|
+
yield* once(window, "offline");
|
|
21
|
+
return false;
|
|
22
|
+
})()]))) {
|
|
23
|
+
connectivity.setConnected(false);
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
if (connectivity.isConnected) continue;
|
|
27
|
+
const stabilized = yield* race([(function* () {
|
|
28
|
+
yield* sleep(ONLINE_STABILIZATION_MS);
|
|
29
|
+
return navigator.onLine;
|
|
30
|
+
})(), (function* () {
|
|
31
|
+
yield* once(window, "offline");
|
|
32
|
+
return false;
|
|
33
|
+
})()]);
|
|
34
|
+
connectivity.setConnected(stabilized);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
connectivity.lifetime.catch(() => void 0);
|
|
38
|
+
return connectivity;
|
|
39
|
+
}
|
|
40
|
+
get isConnected() {
|
|
41
|
+
return this.connected;
|
|
42
|
+
}
|
|
43
|
+
subscribe(listener) {
|
|
44
|
+
this.listeners.add(listener);
|
|
45
|
+
return () => {
|
|
46
|
+
this.listeners.delete(listener);
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
close() {
|
|
50
|
+
this.closePromise ??= Promise.resolve(this.lifetime.halt()).finally(() => {
|
|
51
|
+
this.listeners.clear();
|
|
52
|
+
});
|
|
53
|
+
return this.closePromise;
|
|
54
|
+
}
|
|
55
|
+
setConnected(isConnected) {
|
|
56
|
+
if (isConnected === this.connected) return;
|
|
57
|
+
this.connected = isConnected;
|
|
58
|
+
for (const listener of this.listeners) listener(isConnected);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
//#endregion
|
|
62
|
+
export { NavigatorNetworkConnectivity };
|
|
63
|
+
|
|
71
64
|
//# sourceMappingURL=NavigatorNetworkConnectivity.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NavigatorNetworkConnectivity.js","
|
|
1
|
+
{"version":3,"file":"NavigatorNetworkConnectivity.js","names":[],"sources":["../src/NavigatorNetworkConnectivity.ts"],"sourcesContent":["import { once, race, run, sleep, type Task } from \"effection\";\nimport type { NetworkConnectivity } from \"@party-stack/runtime\";\n\nconst ONLINE_STABILIZATION_MS = 1_000;\n\nexport class NavigatorNetworkConnectivity implements NetworkConnectivity {\n private readonly listeners = new Set<(isConnected: boolean) => void>();\n private lifetime!: Task<void>;\n private connected: boolean;\n private closePromise: Promise<void> | undefined;\n\n private constructor(initiallyConnected: boolean) {\n this.connected = initiallyConnected;\n }\n\n static create(): NavigatorNetworkConnectivity {\n const connectivity = new NavigatorNetworkConnectivity(navigator.onLine);\n connectivity.lifetime = run(function* () {\n while (true) {\n const online = yield* race([\n (function* () {\n yield* once(window, \"online\");\n return true;\n })(),\n (function* () {\n yield* once(window, \"offline\");\n return false;\n })(),\n ]);\n if (!online) {\n connectivity.setConnected(false);\n continue;\n }\n if (connectivity.isConnected) continue;\n\n const stabilized = yield* race([\n (function* () {\n yield* sleep(ONLINE_STABILIZATION_MS);\n return navigator.onLine;\n })(),\n (function* () {\n yield* once(window, \"offline\");\n return false;\n })(),\n ]);\n connectivity.setConnected(stabilized);\n }\n });\n void connectivity.lifetime.catch(() => undefined);\n return connectivity;\n }\n\n get isConnected(): boolean {\n return this.connected;\n }\n\n subscribe(listener: (isConnected: boolean) => void): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n close(): Promise<void> {\n this.closePromise ??= Promise.resolve(this.lifetime.halt()).finally(() => {\n this.listeners.clear();\n });\n return this.closePromise;\n }\n\n private setConnected(isConnected: boolean): void {\n if (isConnected === this.connected) return;\n this.connected = isConnected;\n for (const listener of this.listeners) {\n listener(isConnected);\n }\n }\n}\n"],"mappings":";;AAGA,MAAM,0BAA0B;AAEhC,IAAa,+BAAb,MAAa,6BAA4D;CACrE,4BAA6B,IAAI,IAAoC;CACrE;CACA;CACA;CAEA,YAAoB,oBAA6B;EAC7C,KAAK,YAAY;CACrB;CAEA,OAAO,SAAuC;EAC1C,MAAM,eAAe,IAAI,6BAA6B,UAAU,MAAM;EACtE,aAAa,WAAW,IAAI,aAAa;GACrC,OAAO,MAAM;IAWT,IAAI,EAAC,OAViB,KAAK,EACtB,aAAa;KACV,OAAO,KAAK,QAAQ,QAAQ;KAC5B,OAAO;IACX,EAAA,CAAG,IACF,aAAa;KACV,OAAO,KAAK,QAAQ,SAAS;KAC7B,OAAO;IACX,EAAA,CAAG,CACP,CAAC,IACY;KACT,aAAa,aAAa,KAAK;KAC/B;IACJ;IACA,IAAI,aAAa,aAAa;IAE9B,MAAM,aAAa,OAAO,KAAK,EAC1B,aAAa;KACV,OAAO,MAAM,uBAAuB;KACpC,OAAO,UAAU;IACrB,EAAA,CAAG,IACF,aAAa;KACV,OAAO,KAAK,QAAQ,SAAS;KAC7B,OAAO;IACX,EAAA,CAAG,CACP,CAAC;IACD,aAAa,aAAa,UAAU;GACxC;EACJ,CAAC;EACD,aAAkB,SAAS,YAAY,KAAA,CAAS;EAChD,OAAO;CACX;CAEA,IAAI,cAAuB;EACvB,OAAO,KAAK;CAChB;CAEA,UAAU,UAAsD;EAC5D,KAAK,UAAU,IAAI,QAAQ;EAC3B,aAAa;GACT,KAAK,UAAU,OAAO,QAAQ;EAClC;CACJ;CAEA,QAAuB;EACnB,KAAK,iBAAiB,QAAQ,QAAQ,KAAK,SAAS,KAAK,CAAC,CAAC,CAAC,cAAc;GACtE,KAAK,UAAU,MAAM;EACzB,CAAC;EACD,OAAO,KAAK;CAChB;CAEA,aAAqB,aAA4B;EAC7C,IAAI,gBAAgB,KAAK,WAAW;EACpC,KAAK,YAAY;EACjB,KAAK,MAAM,YAAY,KAAK,WACxB,SAAS,WAAW;CAE5B;AACJ"}
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { BlobBytesStore } from "@party-stack/runtime";
|
|
2
|
+
//#region src/OPFSBlobBytesStore.d.ts
|
|
2
3
|
export interface OPFSBlobBytesStoreOptions {
|
|
3
|
-
|
|
4
|
+
directoryName: string;
|
|
4
5
|
}
|
|
5
6
|
export declare class OPFSBlobBytesStore implements BlobBytesStore {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
#private;
|
|
8
|
+
constructor(options: OPFSBlobBytesStoreOptions);
|
|
9
|
+
write(id: string, blob: Blob): Promise<void>;
|
|
10
|
+
read(id: string): Promise<Blob>;
|
|
11
|
+
delete(id: string): Promise<void>;
|
|
12
|
+
clear(): Promise<void>;
|
|
12
13
|
}
|
|
14
|
+
//#endregion
|
|
13
15
|
//# sourceMappingURL=OPFSBlobBytesStore.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OPFSBlobBytesStore.d.ts","
|
|
1
|
+
{"version":3,"file":"OPFSBlobBytesStore.d.ts","names":[],"sources":["../src/OPFSBlobBytesStore.ts"],"mappings":";;iBAEiB;EACb;;qBAOS,8BAA8B;;EAGvC,YAAY,SAAS;EAIf,MAAM,YAAY,MAAM,OAAO;EAa/B,KAAK,aAAa,QAAQ;EAM1B,OAAO,aAAa;EAYpB,SAAS"}
|
|
@@ -1,59 +1,46 @@
|
|
|
1
|
+
//#region src/OPFSBlobBytesStore.ts
|
|
1
2
|
function encodeFileName(id) {
|
|
2
|
-
|
|
3
|
-
}
|
|
4
|
-
export class OPFSBlobBytesStore {
|
|
5
|
-
#directoryName;
|
|
6
|
-
constructor(options) {
|
|
7
|
-
this.#directoryName = options.directoryName;
|
|
8
|
-
}
|
|
9
|
-
async write(id, blob) {
|
|
10
|
-
const directory = await this.#directory();
|
|
11
|
-
const fileHandle = await directory.getFileHandle(encodeFileName(id), {
|
|
12
|
-
create: true,
|
|
13
|
-
});
|
|
14
|
-
const writable = await fileHandle.createWritable();
|
|
15
|
-
try {
|
|
16
|
-
await writable.write(blob);
|
|
17
|
-
}
|
|
18
|
-
finally {
|
|
19
|
-
await writable.close();
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
async read(id) {
|
|
23
|
-
const directory = await this.#directory();
|
|
24
|
-
const fileHandle = await directory.getFileHandle(encodeFileName(id));
|
|
25
|
-
return fileHandle.getFile();
|
|
26
|
-
}
|
|
27
|
-
async delete(id) {
|
|
28
|
-
const directory = await this.#directory();
|
|
29
|
-
try {
|
|
30
|
-
await directory.removeEntry(encodeFileName(id));
|
|
31
|
-
}
|
|
32
|
-
catch (error) {
|
|
33
|
-
if (error instanceof DOMException && error.name === "NotFoundError") {
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
throw error;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
async clear() {
|
|
40
|
-
const root = await navigator.storage.getDirectory();
|
|
41
|
-
try {
|
|
42
|
-
await root.removeEntry(this.#directoryName, {
|
|
43
|
-
recursive: true,
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
catch (error) {
|
|
47
|
-
if (error instanceof DOMException &&
|
|
48
|
-
error.name === "NotFoundError") {
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
throw error;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
async #directory() {
|
|
55
|
-
const root = await navigator.storage.getDirectory();
|
|
56
|
-
return root.getDirectoryHandle(this.#directoryName, { create: true });
|
|
57
|
-
}
|
|
3
|
+
return encodeURIComponent(id);
|
|
58
4
|
}
|
|
5
|
+
var OPFSBlobBytesStore = class {
|
|
6
|
+
#directoryName;
|
|
7
|
+
constructor(options) {
|
|
8
|
+
this.#directoryName = options.directoryName;
|
|
9
|
+
}
|
|
10
|
+
async write(id, blob) {
|
|
11
|
+
const writable = await (await (await this.#directory()).getFileHandle(encodeFileName(id), { create: true })).createWritable();
|
|
12
|
+
try {
|
|
13
|
+
await writable.write(blob);
|
|
14
|
+
} finally {
|
|
15
|
+
await writable.close();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
async read(id) {
|
|
19
|
+
return (await (await this.#directory()).getFileHandle(encodeFileName(id))).getFile();
|
|
20
|
+
}
|
|
21
|
+
async delete(id) {
|
|
22
|
+
const directory = await this.#directory();
|
|
23
|
+
try {
|
|
24
|
+
await directory.removeEntry(encodeFileName(id));
|
|
25
|
+
} catch (error) {
|
|
26
|
+
if (error instanceof DOMException && error.name === "NotFoundError") return;
|
|
27
|
+
throw error;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
async clear() {
|
|
31
|
+
const root = await navigator.storage.getDirectory();
|
|
32
|
+
try {
|
|
33
|
+
await root.removeEntry(this.#directoryName, { recursive: true });
|
|
34
|
+
} catch (error) {
|
|
35
|
+
if (error instanceof DOMException && error.name === "NotFoundError") return;
|
|
36
|
+
throw error;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async #directory() {
|
|
40
|
+
return (await navigator.storage.getDirectory()).getDirectoryHandle(this.#directoryName, { create: true });
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
//#endregion
|
|
44
|
+
export { OPFSBlobBytesStore };
|
|
45
|
+
|
|
59
46
|
//# sourceMappingURL=OPFSBlobBytesStore.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OPFSBlobBytesStore.js","
|
|
1
|
+
{"version":3,"file":"OPFSBlobBytesStore.js","names":[],"sources":["../src/OPFSBlobBytesStore.ts"],"sourcesContent":["import type { BlobBytesStore } from \"@party-stack/runtime\";\n\nexport interface OPFSBlobBytesStoreOptions {\n directoryName: string;\n}\n\nfunction encodeFileName(id: string): string {\n return encodeURIComponent(id);\n}\n\nexport class OPFSBlobBytesStore implements BlobBytesStore {\n #directoryName: string;\n\n constructor(options: OPFSBlobBytesStoreOptions) {\n this.#directoryName = options.directoryName;\n }\n\n async write(id: string, blob: Blob): Promise<void> {\n const directory = await this.#directory();\n const fileHandle = await directory.getFileHandle(encodeFileName(id), {\n create: true,\n });\n const writable = await fileHandle.createWritable();\n try {\n await writable.write(blob);\n } finally {\n await writable.close();\n }\n }\n\n async read(id: string): Promise<Blob> {\n const directory = await this.#directory();\n const fileHandle = await directory.getFileHandle(encodeFileName(id));\n return fileHandle.getFile();\n }\n\n async delete(id: string): Promise<void> {\n const directory = await this.#directory();\n try {\n await directory.removeEntry(encodeFileName(id));\n } catch (error) {\n if (error instanceof DOMException && error.name === \"NotFoundError\") {\n return;\n }\n throw error;\n }\n }\n\n async clear(): Promise<void> {\n const root = await navigator.storage.getDirectory();\n try {\n await root.removeEntry(this.#directoryName, {\n recursive: true,\n });\n } catch (error) {\n if (error instanceof DOMException && error.name === \"NotFoundError\") {\n return;\n }\n throw error;\n }\n }\n\n async #directory(): Promise<FileSystemDirectoryHandle> {\n const root = await navigator.storage.getDirectory();\n return root.getDirectoryHandle(this.#directoryName, { create: true });\n }\n}\n"],"mappings":";AAMA,SAAS,eAAe,IAAoB;CACxC,OAAO,mBAAmB,EAAE;AAChC;AAEA,IAAa,qBAAb,MAA0D;CACtD;CAEA,YAAY,SAAoC;EAC5C,KAAK,iBAAiB,QAAQ;CAClC;CAEA,MAAM,MAAM,IAAY,MAA2B;EAK/C,MAAM,WAAW,OAAM,OAHE,MADD,KAAK,WAAW,EAAA,CACL,cAAc,eAAe,EAAE,GAAG,EACjE,QAAQ,KACZ,CAAC,EAAA,CACiC,eAAe;EACjD,IAAI;GACA,MAAM,SAAS,MAAM,IAAI;EAC7B,UAAU;GACN,MAAM,SAAS,MAAM;EACzB;CACJ;CAEA,MAAM,KAAK,IAA2B;EAGlC,QAAO,OADkB,MADD,KAAK,WAAW,EAAA,CACL,cAAc,eAAe,EAAE,CAAC,EAAA,CACjD,QAAQ;CAC9B;CAEA,MAAM,OAAO,IAA2B;EACpC,MAAM,YAAY,MAAM,KAAK,WAAW;EACxC,IAAI;GACA,MAAM,UAAU,YAAY,eAAe,EAAE,CAAC;EAClD,SAAS,OAAO;GACZ,IAAI,iBAAiB,gBAAgB,MAAM,SAAS,iBAChD;GAEJ,MAAM;EACV;CACJ;CAEA,MAAM,QAAuB;EACzB,MAAM,OAAO,MAAM,UAAU,QAAQ,aAAa;EAClD,IAAI;GACA,MAAM,KAAK,YAAY,KAAK,gBAAgB,EACxC,WAAW,KACf,CAAC;EACL,SAAS,OAAO;GACZ,IAAI,iBAAiB,gBAAgB,MAAM,SAAS,iBAChD;GAEJ,MAAM;EACV;CACJ;CAEA,MAAM,aAAiD;EAEnD,QAAO,MADY,UAAU,QAAQ,aAAa,EAAA,CACtC,mBAAmB,KAAK,gBAAgB,EAAE,QAAQ,KAAK,CAAC;CACxE;AACJ"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BrowserAuthentication } from "@party-stack/runtime";
|
|
2
|
+
//#region src/createWebBrowserAuthentication.d.ts
|
|
2
3
|
export declare function createWebBrowserAuthentication(options?: {
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
popupTarget?: string;
|
|
5
|
+
popupFeatures?: string;
|
|
5
6
|
}): BrowserAuthentication;
|
|
7
|
+
//#endregion
|
|
6
8
|
//# sourceMappingURL=createWebBrowserAuthentication.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createWebBrowserAuthentication.d.ts","
|
|
1
|
+
{"version":3,"file":"createWebBrowserAuthentication.d.ts","names":[],"sources":["../src/createWebBrowserAuthentication.ts"],"mappings":";;wBAwBgB,+BACZ;EACI;EACA;IAEL"}
|
|
@@ -1,79 +1,66 @@
|
|
|
1
|
-
import { BrowserAuthenticationCancelledError
|
|
1
|
+
import { BrowserAuthenticationCancelledError } from "@party-stack/runtime";
|
|
2
|
+
//#region src/createWebBrowserAuthentication.ts
|
|
2
3
|
function matchesRedirectUrl(candidate, redirectUrl) {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
actual.pathname === expected.pathname);
|
|
4
|
+
const actual = new URL(candidate);
|
|
5
|
+
const expected = new URL(redirectUrl);
|
|
6
|
+
return actual.origin === expected.origin && actual.pathname === expected.pathname;
|
|
7
7
|
}
|
|
8
8
|
function createRedirectSession() {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
9
|
+
return {
|
|
10
|
+
open(authorizationUrl) {
|
|
11
|
+
location.assign(authorizationUrl);
|
|
12
|
+
return new Promise(() => void 0);
|
|
13
|
+
},
|
|
14
|
+
close() {
|
|
15
|
+
window.stop();
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
18
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}, 250);
|
|
63
|
-
stopWaiting = () => {
|
|
64
|
-
window.clearInterval(timer);
|
|
65
|
-
stopWaiting =
|
|
66
|
-
undefined;
|
|
67
|
-
};
|
|
68
|
-
});
|
|
69
|
-
},
|
|
70
|
-
close() {
|
|
71
|
-
stopWaiting?.();
|
|
72
|
-
popup.close();
|
|
73
|
-
cancel?.();
|
|
74
|
-
},
|
|
75
|
-
};
|
|
76
|
-
},
|
|
77
|
-
};
|
|
19
|
+
function createWebBrowserAuthentication(options = {}) {
|
|
20
|
+
return { start({ redirectUrl, presentation }) {
|
|
21
|
+
if (presentation !== "popup") return createRedirectSession();
|
|
22
|
+
const popup = window.open("about:blank", options.popupTarget ?? "party-stack-authentication", options.popupFeatures ?? "popup=yes,width=500,height=700");
|
|
23
|
+
if (!popup) return createRedirectSession();
|
|
24
|
+
let stopWaiting;
|
|
25
|
+
let cancel;
|
|
26
|
+
return {
|
|
27
|
+
open(authorizationUrl) {
|
|
28
|
+
popup.location.assign(authorizationUrl);
|
|
29
|
+
return new Promise((resolve, reject) => {
|
|
30
|
+
cancel = () => {
|
|
31
|
+
stopWaiting?.();
|
|
32
|
+
cancel = void 0;
|
|
33
|
+
reject(new BrowserAuthenticationCancelledError());
|
|
34
|
+
};
|
|
35
|
+
const timer = window.setInterval(() => {
|
|
36
|
+
if (popup.closed) {
|
|
37
|
+
cancel?.();
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
const current = popup.location.href;
|
|
42
|
+
if (!matchesRedirectUrl(current, redirectUrl)) return;
|
|
43
|
+
stopWaiting?.();
|
|
44
|
+
cancel = void 0;
|
|
45
|
+
popup.close();
|
|
46
|
+
resolve({ callbackUrl: current });
|
|
47
|
+
} catch {}
|
|
48
|
+
}, 250);
|
|
49
|
+
stopWaiting = () => {
|
|
50
|
+
window.clearInterval(timer);
|
|
51
|
+
stopWaiting = void 0;
|
|
52
|
+
};
|
|
53
|
+
});
|
|
54
|
+
},
|
|
55
|
+
close() {
|
|
56
|
+
stopWaiting?.();
|
|
57
|
+
popup.close();
|
|
58
|
+
cancel?.();
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
} };
|
|
78
62
|
}
|
|
63
|
+
//#endregion
|
|
64
|
+
export { createWebBrowserAuthentication };
|
|
65
|
+
|
|
79
66
|
//# sourceMappingURL=createWebBrowserAuthentication.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createWebBrowserAuthentication.js","
|
|
1
|
+
{"version":3,"file":"createWebBrowserAuthentication.js","names":[],"sources":["../src/createWebBrowserAuthentication.ts"],"sourcesContent":["import {\n BrowserAuthenticationCancelledError,\n type BrowserAuthentication,\n type BrowserAuthenticationSession,\n} from \"@party-stack/runtime\";\n\nfunction matchesRedirectUrl(candidate: string, redirectUrl: string): boolean {\n const actual = new URL(candidate);\n const expected = new URL(redirectUrl);\n return actual.origin === expected.origin && actual.pathname === expected.pathname;\n}\n\nfunction createRedirectSession(): BrowserAuthenticationSession {\n return {\n open(authorizationUrl) {\n location.assign(authorizationUrl);\n return new Promise(() => undefined);\n },\n close() {\n window.stop();\n },\n };\n}\n\nexport function createWebBrowserAuthentication(\n options: {\n popupTarget?: string;\n popupFeatures?: string;\n } = {}\n): BrowserAuthentication {\n return {\n start({ redirectUrl, presentation }) {\n if (presentation !== \"popup\") {\n return createRedirectSession();\n }\n const popup = window.open(\n \"about:blank\",\n options.popupTarget ?? \"party-stack-authentication\",\n options.popupFeatures ?? \"popup=yes,width=500,height=700\"\n );\n if (!popup) return createRedirectSession();\n\n let stopWaiting: (() => void) | undefined;\n let cancel: (() => void) | undefined;\n return {\n open(authorizationUrl) {\n popup.location.assign(authorizationUrl);\n return new Promise<{\n callbackUrl: string;\n }>((resolve, reject) => {\n cancel = () => {\n stopWaiting?.();\n cancel = undefined;\n reject(new BrowserAuthenticationCancelledError());\n };\n const timer = window.setInterval(() => {\n if (popup.closed) {\n cancel?.();\n return;\n }\n try {\n const current = popup.location.href;\n if (!matchesRedirectUrl(current, redirectUrl)) {\n return;\n }\n stopWaiting?.();\n cancel = undefined;\n popup.close();\n resolve({\n callbackUrl: current,\n });\n } catch {\n // Cross-origin access is expected until the provider returns.\n }\n }, 250);\n stopWaiting = () => {\n window.clearInterval(timer);\n stopWaiting = undefined;\n };\n });\n },\n close() {\n stopWaiting?.();\n popup.close();\n cancel?.();\n },\n };\n },\n };\n}\n"],"mappings":";;AAMA,SAAS,mBAAmB,WAAmB,aAA8B;CACzE,MAAM,SAAS,IAAI,IAAI,SAAS;CAChC,MAAM,WAAW,IAAI,IAAI,WAAW;CACpC,OAAO,OAAO,WAAW,SAAS,UAAU,OAAO,aAAa,SAAS;AAC7E;AAEA,SAAS,wBAAsD;CAC3D,OAAO;EACH,KAAK,kBAAkB;GACnB,SAAS,OAAO,gBAAgB;GAChC,OAAO,IAAI,cAAc,KAAA,CAAS;EACtC;EACA,QAAQ;GACJ,OAAO,KAAK;EAChB;CACJ;AACJ;AAEA,SAAgB,+BACZ,UAGI,CAAC,GACgB;CACrB,OAAO,EACH,MAAM,EAAE,aAAa,gBAAgB;EACjC,IAAI,iBAAiB,SACjB,OAAO,sBAAsB;EAEjC,MAAM,QAAQ,OAAO,KACjB,eACA,QAAQ,eAAe,8BACvB,QAAQ,iBAAiB,gCAC7B;EACA,IAAI,CAAC,OAAO,OAAO,sBAAsB;EAEzC,IAAI;EACJ,IAAI;EACJ,OAAO;GACH,KAAK,kBAAkB;IACnB,MAAM,SAAS,OAAO,gBAAgB;IACtC,OAAO,IAAI,SAEP,SAAS,WAAW;KACpB,eAAe;MACX,cAAc;MACd,SAAS,KAAA;MACT,OAAO,IAAI,oCAAoC,CAAC;KACpD;KACA,MAAM,QAAQ,OAAO,kBAAkB;MACnC,IAAI,MAAM,QAAQ;OACd,SAAS;OACT;MACJ;MACA,IAAI;OACA,MAAM,UAAU,MAAM,SAAS;OAC/B,IAAI,CAAC,mBAAmB,SAAS,WAAW,GACxC;OAEJ,cAAc;OACd,SAAS,KAAA;OACT,MAAM,MAAM;OACZ,QAAQ,EACJ,aAAa,QACjB,CAAC;MACL,QAAQ,CAER;KACJ,GAAG,GAAG;KACN,oBAAoB;MAChB,OAAO,cAAc,KAAK;MAC1B,cAAc,KAAA;KAClB;IACJ,CAAC;GACL;GACA,QAAQ;IACJ,cAAc;IACd,MAAM,MAAM;IACZ,SAAS;GACb;EACJ;CACJ,EACJ;AACJ"}
|
|
@@ -1,2 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import { RuntimeAdapter } from "@party-stack/runtime";
|
|
2
|
+
//#region src/createWebRuntime.d.ts
|
|
3
|
+
export declare const createWebRuntime: (owner: string, namespace: string) => RuntimeAdapter;
|
|
4
|
+
//#endregion
|
|
2
5
|
//# sourceMappingURL=createWebRuntime.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createWebRuntime.d.ts","
|
|
1
|
+
{"version":3,"file":"createWebRuntime.d.ts","names":[],"sources":["../src/createWebRuntime.ts"],"mappings":";;qBAuBa,mBAAmB,eAAe,sBAAsB"}
|
package/lib/createWebRuntime.js
CHANGED
|
@@ -1,50 +1,43 @@
|
|
|
1
|
-
import { LockBroadcastCoordination } from "@party-stack/coordination";
|
|
2
|
-
import { IndexedDBPersistenceAdapter } from "@party-stack/db-indexeddb-persistence";
|
|
3
|
-
import { defineRuntime } from "@party-stack/runtime";
|
|
4
|
-
import { createWebBrowserAuthentication, } from "./createWebBrowserAuthentication.js";
|
|
5
1
|
import { NavigatorNetworkConnectivity } from "./NavigatorNetworkConnectivity.js";
|
|
6
2
|
import { OPFSBlobBytesStore } from "./OPFSBlobBytesStore.js";
|
|
3
|
+
import { createWebBrowserAuthentication } from "./createWebBrowserAuthentication.js";
|
|
4
|
+
import { defineRuntime } from "@party-stack/runtime";
|
|
5
|
+
import { LockBroadcastCoordination } from "@party-stack/coordination";
|
|
6
|
+
import { createIndexedDBPersistence } from "@party-stack/db-indexeddb-persistence";
|
|
7
|
+
//#region src/createWebRuntime.ts
|
|
7
8
|
function deleteIndexedDB(name) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
request.onblocked = () => reject(new Error(`IndexedDB database "${name}" could not be deleted because it is open.`));
|
|
15
|
-
});
|
|
9
|
+
return new Promise((resolve, reject) => {
|
|
10
|
+
const request = indexedDB.deleteDatabase(name);
|
|
11
|
+
request.onsuccess = () => resolve();
|
|
12
|
+
request.onerror = () => reject(new Error(`IndexedDB database "${name}" could not be deleted.`, { cause: request.error }));
|
|
13
|
+
request.onblocked = () => reject(/* @__PURE__ */ new Error(`IndexedDB database "${name}" could not be deleted because it is open.`));
|
|
14
|
+
});
|
|
16
15
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
blobBytes.clear(),
|
|
41
|
-
]);
|
|
42
|
-
},
|
|
43
|
-
cleanup: async () => {
|
|
44
|
-
await coordination.close();
|
|
45
|
-
await connectivity.close();
|
|
46
|
-
persistence.close();
|
|
47
|
-
},
|
|
48
|
-
};
|
|
16
|
+
const createWebRuntime = defineRuntime((owner, namespace) => {
|
|
17
|
+
const name = `party-stack:${owner}:${namespace}`;
|
|
18
|
+
const persistence = createIndexedDBPersistence({ databaseName: name });
|
|
19
|
+
const connectivity = NavigatorNetworkConnectivity.create();
|
|
20
|
+
const coordination = new LockBroadcastCoordination({ scope: name });
|
|
21
|
+
const blobBytes = new OPFSBlobBytesStore({ directoryName: `${name}:blobs` });
|
|
22
|
+
return {
|
|
23
|
+
owner,
|
|
24
|
+
namespace,
|
|
25
|
+
blobBytes,
|
|
26
|
+
coordination,
|
|
27
|
+
connectivity,
|
|
28
|
+
browserAuthentication: createWebBrowserAuthentication(),
|
|
29
|
+
persistence,
|
|
30
|
+
destroy: async () => {
|
|
31
|
+
await Promise.all([deleteIndexedDB(name), blobBytes.clear()]);
|
|
32
|
+
},
|
|
33
|
+
cleanup: async () => {
|
|
34
|
+
await coordination.close();
|
|
35
|
+
await connectivity.close();
|
|
36
|
+
persistence.close();
|
|
37
|
+
}
|
|
38
|
+
};
|
|
49
39
|
});
|
|
40
|
+
//#endregion
|
|
41
|
+
export { createWebRuntime };
|
|
42
|
+
|
|
50
43
|
//# sourceMappingURL=createWebRuntime.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createWebRuntime.js","
|
|
1
|
+
{"version":3,"file":"createWebRuntime.js","names":[],"sources":["../src/createWebRuntime.ts"],"sourcesContent":["import { LockBroadcastCoordination } from \"@party-stack/coordination\";\nimport { createIndexedDBPersistence } from \"@party-stack/db-indexeddb-persistence\";\nimport { defineRuntime } from \"@party-stack/runtime\";\nimport { createWebBrowserAuthentication } from \"./createWebBrowserAuthentication.js\";\nimport { NavigatorNetworkConnectivity } from \"./NavigatorNetworkConnectivity.js\";\nimport { OPFSBlobBytesStore } from \"./OPFSBlobBytesStore.js\";\nimport type { RuntimeAdapter } from \"@party-stack/runtime\";\n\nfunction deleteIndexedDB(name: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const request = indexedDB.deleteDatabase(name);\n request.onsuccess = () => resolve();\n request.onerror = () =>\n reject(\n new Error(`IndexedDB database \"${name}\" could not be deleted.`, {\n cause: request.error,\n })\n );\n request.onblocked = () =>\n reject(new Error(`IndexedDB database \"${name}\" could not be deleted because it is open.`));\n });\n}\n\nexport const createWebRuntime: (owner: string, namespace: string) => RuntimeAdapter = defineRuntime(\n (owner, namespace) => {\n const name = `party-stack:${owner}:${namespace}`;\n const persistence = createIndexedDBPersistence({\n databaseName: name,\n });\n const connectivity = NavigatorNetworkConnectivity.create();\n const coordination = new LockBroadcastCoordination({\n scope: name,\n });\n const blobBytes = new OPFSBlobBytesStore({\n directoryName: `${name}:blobs`,\n });\n return {\n owner,\n namespace,\n blobBytes,\n coordination,\n connectivity,\n browserAuthentication: createWebBrowserAuthentication(),\n persistence,\n destroy: async () => {\n await Promise.all([deleteIndexedDB(name), blobBytes.clear()]);\n },\n cleanup: async () => {\n await coordination.close();\n await connectivity.close();\n persistence.close();\n },\n };\n }\n);\n"],"mappings":";;;;;;;AAQA,SAAS,gBAAgB,MAA6B;CAClD,OAAO,IAAI,SAAS,SAAS,WAAW;EACpC,MAAM,UAAU,UAAU,eAAe,IAAI;EAC7C,QAAQ,kBAAkB,QAAQ;EAClC,QAAQ,gBACJ,OACI,IAAI,MAAM,uBAAuB,KAAK,0BAA0B,EAC5D,OAAO,QAAQ,MACnB,CAAC,CACL;EACJ,QAAQ,kBACJ,uBAAO,IAAI,MAAM,uBAAuB,KAAK,2CAA2C,CAAC;CACjG,CAAC;AACL;AAEA,MAAa,mBAAyE,eACjF,OAAO,cAAc;CAClB,MAAM,OAAO,eAAe,MAAM,GAAG;CACrC,MAAM,cAAc,2BAA2B,EAC3C,cAAc,KAClB,CAAC;CACD,MAAM,eAAe,6BAA6B,OAAO;CACzD,MAAM,eAAe,IAAI,0BAA0B,EAC/C,OAAO,KACX,CAAC;CACD,MAAM,YAAY,IAAI,mBAAmB,EACrC,eAAe,GAAG,KAAK,QAC3B,CAAC;CACD,OAAO;EACH;EACA;EACA;EACA;EACA;EACA,uBAAuB,+BAA+B;EACtD;EACA,SAAS,YAAY;GACjB,MAAM,QAAQ,IAAI,CAAC,gBAAgB,IAAI,GAAG,UAAU,MAAM,CAAC,CAAC;EAChE;EACA,SAAS,YAAY;GACjB,MAAM,aAAa,MAAM;GACzB,MAAM,aAAa,MAAM;GACzB,YAAY,MAAM;EACtB;CACJ;AACJ,CACJ"}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { createWebRuntime } from "./createWebRuntime.js";
|
|
2
|
+
export { createWebRuntime };
|
package/lib/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { createWebRuntime } from "./createWebRuntime.js";
|
|
2
|
+
export { createWebRuntime };
|
package/package.json
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@party-stack/web-runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
|
+
"files": [
|
|
5
|
+
"lib"
|
|
6
|
+
],
|
|
4
7
|
"type": "module",
|
|
5
8
|
"exports": {
|
|
6
9
|
".": {
|
|
@@ -8,24 +11,22 @@
|
|
|
8
11
|
"default": "./lib/index.js"
|
|
9
12
|
}
|
|
10
13
|
},
|
|
11
|
-
"files": [
|
|
12
|
-
"lib"
|
|
13
|
-
],
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"effection": "^4.0.2",
|
|
16
|
-
"@party-stack/
|
|
17
|
-
"@party-stack/
|
|
18
|
-
"@party-stack/runtime": "0.
|
|
16
|
+
"@party-stack/coordination": "0.3.1",
|
|
17
|
+
"@party-stack/db-indexeddb-persistence": "0.2.1",
|
|
18
|
+
"@party-stack/runtime": "0.4.1"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
|
-
"@
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
21
|
+
"@tanstack/db": "0.12.1",
|
|
22
|
+
"@tanstack/db-sqlite-persistence-core": "0.4.5",
|
|
23
|
+
"playwright": "^1.61.1",
|
|
24
|
+
"typescript": "~7.0.2",
|
|
25
|
+
"vite": "npm:@voidzero-dev/vite-plus-core@1.1.0",
|
|
26
|
+
"vite-plus": "1.1.0",
|
|
27
|
+
"@party-stack/build-config": "0.1.1"
|
|
25
28
|
},
|
|
26
29
|
"scripts": {
|
|
27
|
-
"
|
|
28
|
-
"lint": "eslint",
|
|
29
|
-
"test": "vitest run --pass-with-no-tests"
|
|
30
|
+
"test:browser": "tsc -p tsconfig.e2e.json && vp test run --config vitest.e2e.config.mjs"
|
|
30
31
|
}
|
|
31
32
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"NavigatorNetworkConnectivity.test.d.ts","sourceRoot":"","sources":["../src/NavigatorNetworkConnectivity.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
2
|
-
import { NavigatorNetworkConnectivity } from "./NavigatorNetworkConnectivity.js";
|
|
3
|
-
afterEach(() => {
|
|
4
|
-
vi.useRealTimers();
|
|
5
|
-
vi.unstubAllGlobals();
|
|
6
|
-
});
|
|
7
|
-
function setup(initiallyOnline = false) {
|
|
8
|
-
let online = initiallyOnline;
|
|
9
|
-
const windowTarget = new EventTarget();
|
|
10
|
-
vi.stubGlobal("window", windowTarget);
|
|
11
|
-
vi.stubGlobal("navigator", {
|
|
12
|
-
get onLine() {
|
|
13
|
-
return online;
|
|
14
|
-
},
|
|
15
|
-
});
|
|
16
|
-
return {
|
|
17
|
-
connectivity: NavigatorNetworkConnectivity.create(),
|
|
18
|
-
setOnline: (value) => {
|
|
19
|
-
online = value;
|
|
20
|
-
windowTarget.dispatchEvent(new Event(value ? "online" : "offline"));
|
|
21
|
-
},
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
describe("NavigatorNetworkConnectivity", () => {
|
|
25
|
-
it("waits for an online connection to stabilize", async () => {
|
|
26
|
-
vi.useFakeTimers();
|
|
27
|
-
const { connectivity, setOnline } = setup();
|
|
28
|
-
const listener = vi.fn();
|
|
29
|
-
connectivity.subscribe(listener);
|
|
30
|
-
setOnline(true);
|
|
31
|
-
expect(connectivity.isConnected).toBe(false);
|
|
32
|
-
expect(listener).not.toHaveBeenCalled();
|
|
33
|
-
vi.advanceTimersByTime(999);
|
|
34
|
-
expect(connectivity.isConnected).toBe(false);
|
|
35
|
-
vi.advanceTimersByTime(1);
|
|
36
|
-
expect(connectivity.isConnected).toBe(true);
|
|
37
|
-
expect(listener).toHaveBeenCalledWith(true);
|
|
38
|
-
await connectivity.close();
|
|
39
|
-
});
|
|
40
|
-
it("cancels stabilization when the browser goes offline again", async () => {
|
|
41
|
-
vi.useFakeTimers();
|
|
42
|
-
const { connectivity, setOnline } = setup();
|
|
43
|
-
setOnline(true);
|
|
44
|
-
vi.advanceTimersByTime(500);
|
|
45
|
-
setOnline(false);
|
|
46
|
-
vi.advanceTimersByTime(1_000);
|
|
47
|
-
expect(connectivity.isConnected).toBe(false);
|
|
48
|
-
await connectivity.close();
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
//# sourceMappingURL=NavigatorNetworkConnectivity.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"NavigatorNetworkConnectivity.test.js","sourceRoot":"","sources":["../src/NavigatorNetworkConnectivity.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC7D,OAAO,EAAE,4BAA4B,EAAE,MAAM,mCAAmC,CAAC;AAEjF,SAAS,CAAC,GAAG,EAAE;IACX,EAAE,CAAC,aAAa,EAAE,CAAC;IACnB,EAAE,CAAC,gBAAgB,EAAE,CAAC;AAC1B,CAAC,CAAC,CAAC;AAEH,SAAS,KAAK,CAAC,eAAe,GAAG,KAAK;IAClC,IAAI,MAAM,GAAG,eAAe,CAAC;IAC7B,MAAM,YAAY,GAAG,IAAI,WAAW,EAAE,CAAC;IACvC,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IACtC,EAAE,CAAC,UAAU,CAAC,WAAW,EAAE;QACvB,IAAI,MAAM;YACN,OAAO,MAAM,CAAC;QAClB,CAAC;KACJ,CAAC,CAAC;IACH,OAAO;QACH,YAAY,EAAE,4BAA4B,CAAC,MAAM,EAAE;QACnD,SAAS,EAAE,CAAC,KAAc,EAAE,EAAE;YAC1B,MAAM,GAAG,KAAK,CAAC;YACf,YAAY,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;QACxE,CAAC;KACJ,CAAC;AACN,CAAC;AAED,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;IAC1C,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QACzD,EAAE,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,CAAC;QAC5C,MAAM,QAAQ,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QACzB,YAAY,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAEjC,SAAS,CAAC,IAAI,CAAC,CAAC;QAChB,MAAM,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7C,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAExC,EAAE,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;QAC5B,MAAM,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAE7C,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC;QAC1B,MAAM,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,MAAM,CAAC,QAAQ,CAAC,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC;QAC5C,MAAM,YAAY,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QACvE,EAAE,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,CAAC;QAE5C,SAAS,CAAC,IAAI,CAAC,CAAC;QAChB,EAAE,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;QAC5B,SAAS,CAAC,KAAK,CAAC,CAAC;QACjB,EAAE,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;QAE9B,MAAM,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7C,MAAM,YAAY,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createWebBrowserAuthentication.test.d.ts","sourceRoot":"","sources":["../src/createWebBrowserAuthentication.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { BrowserAuthenticationCancelledError } from "@party-stack/runtime";
|
|
2
|
-
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
3
|
-
import { createWebBrowserAuthentication } from "./createWebBrowserAuthentication.js";
|
|
4
|
-
describe("createWebBrowserAuthentication", () => {
|
|
5
|
-
afterEach(() => {
|
|
6
|
-
vi.useRealTimers();
|
|
7
|
-
vi.unstubAllGlobals();
|
|
8
|
-
});
|
|
9
|
-
it("reserves a popup and resolves its return URL", async () => {
|
|
10
|
-
vi.useFakeTimers();
|
|
11
|
-
const popup = {
|
|
12
|
-
closed: false,
|
|
13
|
-
location: {
|
|
14
|
-
href: "about:blank",
|
|
15
|
-
assign(url) {
|
|
16
|
-
this.href = url;
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
close() {
|
|
20
|
-
this.closed = true;
|
|
21
|
-
},
|
|
22
|
-
};
|
|
23
|
-
vi.stubGlobal("window", {
|
|
24
|
-
open: vi.fn(() => popup),
|
|
25
|
-
setInterval,
|
|
26
|
-
clearInterval,
|
|
27
|
-
});
|
|
28
|
-
const authentication = createWebBrowserAuthentication();
|
|
29
|
-
const session = authentication.start({
|
|
30
|
-
redirectUrl: "https://app.example/auth/callback",
|
|
31
|
-
presentation: "popup",
|
|
32
|
-
});
|
|
33
|
-
const result = session.open("https://auth.example/authorize");
|
|
34
|
-
popup.location.href =
|
|
35
|
-
"https://app.example/auth/callback?code=code";
|
|
36
|
-
await vi.advanceTimersByTimeAsync(250);
|
|
37
|
-
await expect(result).resolves.toEqual({
|
|
38
|
-
callbackUrl: "https://app.example/auth/callback?code=code",
|
|
39
|
-
});
|
|
40
|
-
expect(popup.closed).toBe(true);
|
|
41
|
-
});
|
|
42
|
-
it("rejects the pending operation when closed", async () => {
|
|
43
|
-
vi.useFakeTimers();
|
|
44
|
-
const popup = {
|
|
45
|
-
closed: false,
|
|
46
|
-
location: {
|
|
47
|
-
href: "about:blank",
|
|
48
|
-
assign(url) {
|
|
49
|
-
this.href = url;
|
|
50
|
-
},
|
|
51
|
-
},
|
|
52
|
-
close() {
|
|
53
|
-
this.closed = true;
|
|
54
|
-
},
|
|
55
|
-
};
|
|
56
|
-
vi.stubGlobal("window", {
|
|
57
|
-
open: vi.fn(() => popup),
|
|
58
|
-
setInterval,
|
|
59
|
-
clearInterval,
|
|
60
|
-
});
|
|
61
|
-
const authentication = createWebBrowserAuthentication();
|
|
62
|
-
const session = authentication.start({
|
|
63
|
-
redirectUrl: "https://app.example/auth/callback",
|
|
64
|
-
presentation: "popup",
|
|
65
|
-
});
|
|
66
|
-
const result = session.open("https://auth.example/authorize");
|
|
67
|
-
await session.close();
|
|
68
|
-
await expect(result).rejects.toBeInstanceOf(BrowserAuthenticationCancelledError);
|
|
69
|
-
});
|
|
70
|
-
});
|
|
71
|
-
//# sourceMappingURL=createWebBrowserAuthentication.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createWebBrowserAuthentication.test.js","sourceRoot":"","sources":["../src/createWebBrowserAuthentication.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mCAAmC,EAAE,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC7D,OAAO,EAAE,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;AAErF,QAAQ,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC5C,SAAS,CAAC,GAAG,EAAE;QACX,EAAE,CAAC,aAAa,EAAE,CAAC;QACnB,EAAE,CAAC,gBAAgB,EAAE,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAC1D,EAAE,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,KAAK,GAAG;YACV,MAAM,EAAE,KAAK;YACb,QAAQ,EAAE;gBACN,IAAI,EAAE,aAAa;gBACnB,MAAM,CAAC,GAAW;oBACd,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;gBACpB,CAAC;aACJ;YACD,KAAK;gBACD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YACvB,CAAC;SACJ,CAAC;QACF,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE;YACpB,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC;YACxB,WAAW;YACX,aAAa;SAChB,CAAC,CAAC;QACH,MAAM,cAAc,GAChB,8BAA8B,EAAE,CAAC;QAErC,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC;YACjC,WAAW,EACP,mCAAmC;YACvC,YAAY,EAAE,OAAO;SACxB,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CACvB,gCAAgC,CACnC,CAAC;QACF,KAAK,CAAC,QAAQ,CAAC,IAAI;YACf,6CAA6C,CAAC;QAClD,MAAM,EAAE,CAAC,wBAAwB,CAAC,GAAG,CAAC,CAAC;QAEvC,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;YAClC,WAAW,EACP,6CAA6C;SACpD,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;QACvD,EAAE,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,KAAK,GAAG;YACV,MAAM,EAAE,KAAK;YACb,QAAQ,EAAE;gBACN,IAAI,EAAE,aAAa;gBACnB,MAAM,CAAC,GAAW;oBACd,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;gBACpB,CAAC;aACJ;YACD,KAAK;gBACD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YACvB,CAAC;SACJ,CAAC;QACF,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE;YACpB,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC;YACxB,WAAW;YACX,aAAa;SAChB,CAAC,CAAC;QACH,MAAM,cAAc,GAChB,8BAA8B,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC;YACjC,WAAW,EACP,mCAAmC;YACvC,YAAY,EAAE,OAAO;SACxB,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CACvB,gCAAgC,CACnC,CAAC;QAEF,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QAEtB,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,cAAc,CACvC,mCAAmC,CACtC,CAAC;IACN,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
package/lib/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC"}
|
package/lib/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC"}
|