diff --git a/npm/ng-packs/packages/oauth/package.json b/npm/ng-packs/packages/oauth/package.json
index 99c4a06485..60839d84fb 100644
--- a/npm/ng-packs/packages/oauth/package.json
+++ b/npm/ng-packs/packages/oauth/package.json
@@ -6,6 +6,9 @@
"type": "git",
"url": "https://github.com/abpframework/abp.git"
},
+ "scripts": {
+ "build:worker": "esbuild src/lib/workers/token-storage.worker.ts --bundle --format=esm --target=es2022 --outfile=src/lib/workers/token-storage.worker.js"
+ },
"dependencies": {
"@abp/ng.core": "~10.0.1",
"@abp/utils": "~10.0.1",
diff --git a/npm/ng-packs/packages/oauth/project.json b/npm/ng-packs/packages/oauth/project.json
index 61662f4811..98c7cba04f 100644
--- a/npm/ng-packs/packages/oauth/project.json
+++ b/npm/ng-packs/packages/oauth/project.json
@@ -5,6 +5,13 @@
"sourceRoot": "packages/oauth/src",
"prefix": "abp",
"targets": {
+ "build-worker": {
+ "executor": "nx:run-commands",
+ "options": {
+ "command": "esbuild src/lib/workers/token-storage.worker.ts --bundle --format=esm --target=es2022 --outfile=src/lib/workers/token-storage.worker.js",
+ "cwd": "packages/oauth"
+ }
+ },
"build": {
"executor": "@nx/angular:package",
"outputs": ["{workspaceRoot}/dist/packages/oauth"],
@@ -19,7 +26,8 @@
"tsConfig": "packages/oauth/tsconfig.lib.json"
}
},
- "defaultConfiguration": "production"
+ "defaultConfiguration": "production",
+ "dependsOn": ["build-worker"]
},
"test": {
"executor": "@nx/jest:jest",
diff --git a/npm/ng-packs/packages/oauth/src/lib/services/memory-token-storage.service.ts b/npm/ng-packs/packages/oauth/src/lib/services/memory-token-storage.service.ts
index 218b02ac22..06402c842b 100644
--- a/npm/ng-packs/packages/oauth/src/lib/services/memory-token-storage.service.ts
+++ b/npm/ng-packs/packages/oauth/src/lib/services/memory-token-storage.service.ts
@@ -31,7 +31,7 @@ export class MemoryTokenStorageService implements OAuthStorage {
// @ts-ignore
this.worker = new SharedWorker(
new URL(
- '../workers/token-storage.worker.js',
+ '../workers/token-storage.worker.ts',
import.meta.url
),
{ name: 'oauth-token-storage', type: "module" }
diff --git a/npm/ng-packs/packages/oauth/src/lib/workers/token-storage.worker.js b/npm/ng-packs/packages/oauth/src/lib/workers/token-storage.worker.js
index 2e12c54b07..b4032ce09a 100644
--- a/npm/ng-packs/packages/oauth/src/lib/workers/token-storage.worker.js
+++ b/npm/ng-packs/packages/oauth/src/lib/workers/token-storage.worker.js
@@ -1,65 +1,62 @@
-// ESM SharedWorker
-
-const tokenStore = new Map();
-const ports = new Set();
-
-// Broadcast message to all ports except the sender and remove dead ports
+// src/lib/workers/token-storage.worker.ts
+var tokenStore = /* @__PURE__ */ new Map();
+var ports = /* @__PURE__ */ new Set();
function broadcastToOtherPorts(senderPort, message) {
const deadPorts = [];
-
- ports.forEach(p => {
+ ports.forEach((p) => {
if (p !== senderPort) {
try {
p.postMessage(message);
} catch (error) {
- console.log('Dead port detected, removing...');
+ console.log("Dead port detected, removing...");
deadPorts.push(p);
}
}
});
-
- // Clean up dead ports
- deadPorts.forEach(p => ports.delete(p));
+ deadPorts.forEach((p) => ports.delete(p));
+ if (deadPorts.length > 0) {
+ console.log("Cleaned up dead ports. Total ports:", ports.size);
+ }
}
-
self.onconnect = (event) => {
const port = event.ports[0];
ports.add(port);
-
- // Clean up port when it's closed
- port.addEventListener('messageerror', () => {
+ console.log("Port connected. Total ports:", ports.size);
+ port.addEventListener("messageerror", () => {
ports.delete(port);
- console.log('Port disconnected (error). Total ports:', ports.size);
+ console.log("Port disconnected (error). Total ports:", ports.size);
});
-
port.onmessage = (e) => {
const { action, key, value } = e.data;
switch (action) {
- case 'set':
- if (key && value !== undefined) {
+ case "set":
+ if (key && value !== void 0) {
tokenStore.set(key, value);
- broadcastToOtherPorts(port, { action: 'set', key, value });
+ broadcastToOtherPorts(port, { action: "set", key, value });
}
break;
- case 'remove':
+ case "remove":
if (key) {
+ console.log("remove", key);
tokenStore.delete(key);
- broadcastToOtherPorts(port, { action: 'remove', key });
+ broadcastToOtherPorts(port, { action: "remove", key });
}
break;
- case 'clear':
+ case "clear":
+ console.log("clear user");
tokenStore.clear();
- broadcastToOtherPorts(port, { action: 'clear' });
+ broadcastToOtherPorts(port, { action: "clear" });
break;
- case 'get':
+ case "get":
+ console.log("get user");
if (key) {
- const value = tokenStore.get(key) ?? null;
- port.postMessage({ action: 'get', key, value });
+ const value2 = tokenStore.get(key) ?? null;
+ port.postMessage({ action: "get", key, value: value2 });
}
break;
+ default:
+ console.warn("Unknown action:", action);
}
};
port.start();
};
-
-export {};
diff --git a/npm/ng-packs/packages/oauth/src/lib/workers/token-storage.worker.ts b/npm/ng-packs/packages/oauth/src/lib/workers/token-storage.worker.ts
new file mode 100644
index 0000000000..a5c422738a
--- /dev/null
+++ b/npm/ng-packs/packages/oauth/src/lib/workers/token-storage.worker.ts
@@ -0,0 +1,98 @@
+///
+
+// Message types for type safety
+interface TokenMessage {
+ action: 'set' | 'remove' | 'clear' | 'get';
+ key?: string;
+ value?: string;
+}
+
+interface TokenResponse {
+ action: 'set' | 'remove' | 'clear' | 'get';
+ key?: string;
+ value?: string | null;
+}
+
+declare const self: SharedWorkerGlobalScope;
+
+const tokenStore = new Map();
+const ports = new Set();
+
+// Broadcast message to all ports except the sender
+// Automatically cleans up dead ports
+function broadcastToOtherPorts(senderPort: MessagePort, message: TokenResponse): void {
+ const deadPorts: MessagePort[] = [];
+
+ ports.forEach(p => {
+ if (p !== senderPort) {
+ try {
+ p.postMessage(message);
+ } catch (error) {
+ // Port is dead/closed, mark for removal
+ console.log('Dead port detected, removing...');
+ deadPorts.push(p);
+ }
+ }
+ });
+
+ // Clean up dead ports
+ deadPorts.forEach(p => ports.delete(p));
+
+ if (deadPorts.length > 0) {
+ console.log('Cleaned up dead ports. Total ports:', ports.size);
+ }
+}
+
+self.onconnect = (event: MessageEvent) => {
+ const port = event.ports[0];
+ ports.add(port);
+ console.log('Port connected. Total ports:', ports.size);
+
+ // Clean up port when it's closed
+ port.addEventListener('messageerror', () => {
+ ports.delete(port);
+ console.log('Port disconnected (error). Total ports:', ports.size);
+ });
+
+ port.onmessage = (e: MessageEvent) => {
+ const { action, key, value } = e.data;
+
+ switch (action) {
+ case 'set':
+ if (key && value !== undefined) {
+ tokenStore.set(key, value);
+ broadcastToOtherPorts(port, { action: 'set', key, value });
+ }
+ break;
+
+ case 'remove':
+ if (key) {
+ console.log('remove', key);
+ tokenStore.delete(key);
+ broadcastToOtherPorts(port, { action: 'remove', key });
+ }
+ break;
+
+ case 'clear':
+ console.log('clear user');
+ tokenStore.clear();
+ broadcastToOtherPorts(port, { action: 'clear' });
+ break;
+
+ case 'get':
+ console.log('get user');
+ if (key) {
+ const value = tokenStore.get(key) ?? null;
+ port.postMessage({ action: 'get', key, value } as TokenResponse);
+ }
+ break;
+
+ default:
+ console.warn('Unknown action:', action);
+ }
+ };
+
+ port.start();
+};
+
+export {};