@floegence/flowersec-core 0.27.0 → 2.1.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.
Files changed (268) hide show
  1. package/README.md +91 -22
  2. package/THIRD_PARTY_NOTICES.md +141 -0
  3. package/dist/browser/connectSession.d.ts +13 -0
  4. package/dist/browser/connectSession.js +40 -0
  5. package/dist/browser/index.d.ts +3 -10
  6. package/dist/browser/index.js +2 -5
  7. package/dist/browser/runtimeCapability.d.ts +13 -0
  8. package/dist/browser/runtimeCapability.js +27 -0
  9. package/dist/browser/sessionRuntime.d.ts +2 -0
  10. package/dist/browser/sessionRuntime.js +21 -0
  11. package/dist/browser/webTransportClient.d.ts +8 -0
  12. package/dist/browser/webTransportClient.js +55 -0
  13. package/dist/cli.d.ts +2 -0
  14. package/dist/cli.js +126 -0
  15. package/dist/cliSpendMarker.d.ts +1 -0
  16. package/dist/cliSpendMarker.js +22 -0
  17. package/dist/connectionController.d.ts +54 -0
  18. package/dist/connectionController.js +438 -0
  19. package/dist/connector/adapters/webSocketCandidate.d.ts +7 -0
  20. package/dist/connector/adapters/webSocketCandidate.js +116 -0
  21. package/dist/connector/adapters/webTransportCandidate.d.ts +5 -0
  22. package/dist/connector/adapters/webTransportCandidate.js +73 -0
  23. package/dist/connector/admissionCommit.d.ts +31 -0
  24. package/dist/connector/admissionCommit.js +239 -0
  25. package/dist/connector/sessionAcceptor.d.ts +16 -0
  26. package/dist/connector/sessionAcceptor.js +114 -0
  27. package/dist/connector/sessionConfig.d.ts +3 -0
  28. package/dist/connector/sessionConfig.js +30 -0
  29. package/dist/connector/sessionConnector.d.ts +45 -0
  30. package/dist/connector/sessionConnector.js +603 -0
  31. package/dist/defaults.d.ts +7 -7
  32. package/dist/defaults.js +7 -7
  33. package/dist/facade.d.ts +12 -27
  34. package/dist/facade.js +6 -24
  35. package/dist/node/connectSession.d.ts +21 -0
  36. package/dist/node/connectSession.js +62 -0
  37. package/dist/node/index.d.ts +3 -11
  38. package/dist/node/index.js +2 -8
  39. package/dist/node/runtimeCapability.d.ts +7 -0
  40. package/dist/node/runtimeCapability.js +10 -0
  41. package/dist/node/sessionRuntime.d.ts +2 -0
  42. package/dist/node/sessionRuntime.js +13 -0
  43. package/dist/node/webTransportClient.d.ts +9 -0
  44. package/dist/node/webTransportClient.js +56 -0
  45. package/dist/node/webTransportServer.d.ts +22 -0
  46. package/dist/node/webTransportServer.js +100 -0
  47. package/dist/node/wsFactory.d.ts +3 -1
  48. package/dist/node/wsFactory.js +4 -3
  49. package/dist/proxy/controllerGuard.d.ts +4 -4
  50. package/dist/proxy/controllerGuard.js +83 -177
  51. package/dist/proxy/disableUpstreamServiceWorkerRegister.d.ts +3 -1
  52. package/dist/proxy/disableUpstreamServiceWorkerRegister.js +19 -17
  53. package/dist/proxy/index.d.ts +16 -15
  54. package/dist/proxy/index.js +8 -14
  55. package/dist/proxy/integration.d.ts +23 -71
  56. package/dist/proxy/integration.js +37 -340
  57. package/dist/proxy/registerServiceWorker.d.ts +1 -10
  58. package/dist/proxy/registerServiceWorker.js +43 -105
  59. package/dist/proxy/runtime.d.ts +3 -63
  60. package/dist/proxy/runtime.js +349 -462
  61. package/dist/proxy/scope.d.ts +6 -0
  62. package/dist/proxy/scope.js +131 -0
  63. package/dist/proxy/serviceWorker.d.ts +5 -16
  64. package/dist/proxy/serviceWorker.js +230 -617
  65. package/dist/proxy/stream.d.ts +9 -0
  66. package/dist/proxy/stream.js +40 -0
  67. package/dist/proxy/types.d.ts +78 -30
  68. package/dist/proxy/windowBridge.d.ts +61 -0
  69. package/dist/proxy/windowBridge.js +344 -0
  70. package/dist/proxy/wsPatch.d.ts +4 -14
  71. package/dist/proxy/wsPatch.js +173 -268
  72. package/dist/public/artifact.d.ts +11 -0
  73. package/dist/public/artifact.js +44 -0
  74. package/dist/public/artifactLease.d.ts +10 -0
  75. package/dist/public/artifactLease.js +48 -0
  76. package/dist/public/connectError.d.ts +6 -0
  77. package/dist/public/connectError.js +9 -0
  78. package/dist/public/contract.d.ts +83 -0
  79. package/dist/public/contract.js +17 -0
  80. package/dist/public/streamMetadata.d.ts +10 -0
  81. package/dist/public/streamMetadata.js +40 -0
  82. package/dist/rpc/caller.d.ts +1 -1
  83. package/dist/rpc/client.d.ts +1 -4
  84. package/dist/rpc/client.js +0 -21
  85. package/dist/rpc/rpcProxy.d.ts +1 -1
  86. package/dist/rpc/server.d.ts +1 -1
  87. package/dist/rpc/validate.d.ts +1 -1
  88. package/dist/rpc/wire.d.ts +15 -0
  89. package/dist/runtime/errors.d.ts +6 -0
  90. package/dist/runtime/errors.js +10 -0
  91. package/dist/transport/webSocketAdapter.d.ts +24 -0
  92. package/dist/transport/webSocketAdapter.js +234 -0
  93. package/dist/transport/webTransportAdapter.d.ts +27 -0
  94. package/dist/transport/webTransportAdapter.js +519 -0
  95. package/dist/utils/errors.d.ts +2 -20
  96. package/dist/utils/errors.js +73 -20
  97. package/dist/v2/admissionError.d.ts +4 -0
  98. package/dist/v2/admissionError.js +8 -0
  99. package/dist/v2/artifact.d.ts +128 -0
  100. package/dist/v2/artifact.js +1126 -0
  101. package/dist/v2/artifactLease.d.ts +1 -0
  102. package/dist/v2/artifactLease.js +7 -0
  103. package/dist/v2/capability.d.ts +29 -0
  104. package/dist/v2/capability.js +190 -0
  105. package/dist/v2/carrier.d.ts +79 -0
  106. package/dist/v2/carrier.js +405 -0
  107. package/dist/v2/contract.d.ts +37 -0
  108. package/dist/v2/contract.js +1 -0
  109. package/dist/v2/handshake.d.ts +80 -0
  110. package/dist/v2/handshake.js +470 -0
  111. package/dist/v2/opaqueArtifact.d.ts +1 -0
  112. package/dist/v2/opaqueArtifact.js +2 -0
  113. package/dist/v2/protocol.d.ts +99 -0
  114. package/dist/v2/protocol.js +739 -0
  115. package/dist/v2/publicSession.d.ts +1 -0
  116. package/dist/v2/publicSession.js +179 -0
  117. package/dist/v2/retryDisposition.d.ts +16 -0
  118. package/dist/v2/retryDisposition.js +30 -0
  119. package/dist/v2/session.d.ts +277 -0
  120. package/dist/v2/session.js +1879 -0
  121. package/dist/v2/streamLifetimeLedger.d.ts +31 -0
  122. package/dist/v2/streamLifetimeLedger.js +131 -0
  123. package/dist/v2/streamMetadata.d.ts +1 -0
  124. package/dist/v2/streamMetadata.js +7 -0
  125. package/dist/v2/unreliableMessage.d.ts +43 -0
  126. package/dist/v2/unreliableMessage.js +252 -0
  127. package/dist/vendor/tr46.d.ts +10 -0
  128. package/dist/vendor/tr46.js +501 -0
  129. package/dist/ws-client/binaryTransport.d.ts +0 -3
  130. package/dist/ws-client/binaryTransport.js +15 -39
  131. package/dist/yamux/errors.d.ts +0 -4
  132. package/dist/yamux/errors.js +0 -9
  133. package/dist/yamux/session.d.ts +0 -5
  134. package/dist/yamux/session.js +4 -70
  135. package/dist/yamux/stream.d.ts +1 -0
  136. package/dist/yamux/stream.js +4 -0
  137. package/package.json +29 -81
  138. package/sbom/cyclonedx.json +2764 -0
  139. package/sbom/spdx.json +1947 -0
  140. package/YAMUX_ALIGNMENT.md +0 -127
  141. package/dist/_examples/flowersec/demo/v1.facade.gen.d.ts +0 -12
  142. package/dist/_examples/flowersec/demo/v1.facade.gen.js +0 -15
  143. package/dist/_examples/flowersec/demo/v1.gen.d.ts +0 -16
  144. package/dist/_examples/flowersec/demo/v1.gen.js +0 -86
  145. package/dist/_examples/flowersec/demo/v1.rpc.gen.d.ts +0 -11
  146. package/dist/_examples/flowersec/demo/v1.rpc.gen.js +0 -22
  147. package/dist/browser/connect.d.ts +0 -13
  148. package/dist/browser/connect.js +0 -31
  149. package/dist/browser/reconnectConfig.d.ts +0 -15
  150. package/dist/browser/reconnectConfig.js +0 -20
  151. package/dist/client-connect/common.d.ts +0 -26
  152. package/dist/client-connect/common.js +0 -167
  153. package/dist/client-connect/connectCore.d.ts +0 -61
  154. package/dist/client-connect/connectCore.js +0 -572
  155. package/dist/client-connect/contract.d.ts +0 -8
  156. package/dist/client-connect/contract.js +0 -51
  157. package/dist/client-connect/termination.d.ts +0 -6
  158. package/dist/client-connect/termination.js +0 -7
  159. package/dist/client-connect/transportSecurity.d.ts +0 -27
  160. package/dist/client-connect/transportSecurity.js +0 -199
  161. package/dist/client-connect/tunnelAttachCloseReason.d.ts +0 -3
  162. package/dist/client-connect/tunnelAttachCloseReason.js +0 -23
  163. package/dist/client.d.ts +0 -23
  164. package/dist/connect/artifact.d.ts +0 -36
  165. package/dist/connect/artifact.js +0 -213
  166. package/dist/connect/resolveArtifact.d.ts +0 -22
  167. package/dist/connect/resolveArtifact.js +0 -87
  168. package/dist/controlplane/channelInit.d.ts +0 -27
  169. package/dist/controlplane/channelInit.js +0 -116
  170. package/dist/controlplane/http.d.ts +0 -16
  171. package/dist/controlplane/http.js +0 -59
  172. package/dist/controlplane/index.d.ts +0 -6
  173. package/dist/controlplane/index.js +0 -5
  174. package/dist/controlplane/issuer.d.ts +0 -18
  175. package/dist/controlplane/issuer.js +0 -113
  176. package/dist/controlplane/request.d.ts +0 -51
  177. package/dist/controlplane/request.js +0 -273
  178. package/dist/controlplane/token.d.ts +0 -33
  179. package/dist/controlplane/token.js +0 -119
  180. package/dist/direct-client/connect.d.ts +0 -9
  181. package/dist/direct-client/connect.js +0 -90
  182. package/dist/direct-client/index.d.ts +0 -1
  183. package/dist/direct-client/index.js +0 -1
  184. package/dist/e2ee/constants.d.ts +0 -9
  185. package/dist/e2ee/constants.js +0 -18
  186. package/dist/e2ee/errors.d.ts +0 -5
  187. package/dist/e2ee/errors.js +0 -8
  188. package/dist/e2ee/framing.d.ts +0 -12
  189. package/dist/e2ee/framing.js +0 -57
  190. package/dist/e2ee/handshake.d.ts +0 -88
  191. package/dist/e2ee/handshake.js +0 -353
  192. package/dist/e2ee/index.d.ts +0 -7
  193. package/dist/e2ee/index.js +0 -7
  194. package/dist/e2ee/kdf.d.ts +0 -15
  195. package/dist/e2ee/kdf.js +0 -39
  196. package/dist/e2ee/record.d.ts +0 -11
  197. package/dist/e2ee/record.js +0 -80
  198. package/dist/e2ee/secureChannel.d.ts +0 -93
  199. package/dist/e2ee/secureChannel.js +0 -342
  200. package/dist/e2ee/transcript.d.ts +0 -23
  201. package/dist/e2ee/transcript.js +0 -31
  202. package/dist/endpoint/index.d.ts +0 -84
  203. package/dist/endpoint/index.js +0 -557
  204. package/dist/endpoint/node.d.ts +0 -9
  205. package/dist/endpoint/node.js +0 -51
  206. package/dist/gen/flowersec/controlplane/v1.gen.d.ts +0 -36
  207. package/dist/gen/flowersec/controlplane/v1.gen.js +0 -135
  208. package/dist/gen/flowersec/direct/v1.gen.d.ts +0 -21
  209. package/dist/gen/flowersec/direct/v1.gen.js +0 -101
  210. package/dist/gen/flowersec/e2ee/v1.gen.d.ts +0 -68
  211. package/dist/gen/flowersec/e2ee/v1.gen.js +0 -194
  212. package/dist/gen/flowersec/rpc/v1.gen.d.ts +0 -30
  213. package/dist/gen/flowersec/rpc/v1.gen.js +0 -107
  214. package/dist/gen/flowersec/tunnel/v1.gen.d.ts +0 -23
  215. package/dist/gen/flowersec/tunnel/v1.gen.js +0 -104
  216. package/dist/index.d.ts +0 -22
  217. package/dist/index.js +0 -22
  218. package/dist/node/connect.d.ts +0 -10
  219. package/dist/node/connect.js +0 -29
  220. package/dist/node/reconnectConfig.d.ts +0 -16
  221. package/dist/node/reconnectConfig.js +0 -20
  222. package/dist/observability/index.d.ts +0 -1
  223. package/dist/observability/index.js +0 -1
  224. package/dist/observability/observer.d.ts +0 -52
  225. package/dist/observability/observer.js +0 -314
  226. package/dist/proxy/appWindow.d.ts +0 -37
  227. package/dist/proxy/appWindow.js +0 -273
  228. package/dist/proxy/bootstrap.d.ts +0 -35
  229. package/dist/proxy/bootstrap.js +0 -119
  230. package/dist/proxy/constants.d.ts +0 -7
  231. package/dist/proxy/constants.js +0 -8
  232. package/dist/proxy/controllerWindow.d.ts +0 -12
  233. package/dist/proxy/controllerWindow.js +0 -384
  234. package/dist/proxy/cookieJar.d.ts +0 -7
  235. package/dist/proxy/cookieJar.js +0 -136
  236. package/dist/proxy/headerPolicy.d.ts +0 -14
  237. package/dist/proxy/headerPolicy.js +0 -134
  238. package/dist/proxy/portStream.d.ts +0 -5
  239. package/dist/proxy/portStream.js +0 -256
  240. package/dist/proxy/preset.d.ts +0 -29
  241. package/dist/proxy/preset.js +0 -111
  242. package/dist/proxy/runtimeScope.d.ts +0 -57
  243. package/dist/proxy/runtimeScope.js +0 -218
  244. package/dist/proxy/server.d.ts +0 -28
  245. package/dist/proxy/server.js +0 -833
  246. package/dist/proxy/windowBridgeProtocol.d.ts +0 -65
  247. package/dist/proxy/windowBridgeProtocol.js +0 -11
  248. package/dist/reconnect/artifactControlplane.d.ts +0 -16
  249. package/dist/reconnect/artifactControlplane.js +0 -35
  250. package/dist/reconnect/index.d.ts +0 -36
  251. package/dist/reconnect/index.js +0 -388
  252. package/dist/rpc-proxy/index.d.ts +0 -1
  253. package/dist/rpc-proxy/index.js +0 -1
  254. package/dist/rpc-proxy/rpcProxy.d.ts +0 -1
  255. package/dist/rpc-proxy/rpcProxy.js +0 -1
  256. package/dist/streamhello/index.d.ts +0 -1
  257. package/dist/streamhello/index.js +0 -1
  258. package/dist/streamhello/streamHello.d.ts +0 -3
  259. package/dist/streamhello/streamHello.js +0 -13
  260. package/dist/streamio/index.d.ts +0 -32
  261. package/dist/streamio/index.js +0 -87
  262. package/dist/tunnel-client/connect.d.ts +0 -9
  263. package/dist/tunnel-client/connect.js +0 -147
  264. package/dist/tunnel-client/index.d.ts +0 -1
  265. package/dist/tunnel-client/index.js +0 -1
  266. package/dist/ws/index.d.ts +0 -1
  267. package/dist/ws/index.js +0 -1
  268. /package/dist/{client.js → rpc/wire.js} +0 -0
@@ -1,210 +1,116 @@
1
- function dedupeStrings(values) {
2
- const out = [];
3
- const seen = new Set();
4
- for (const value of values) {
5
- const normalized = String(value ?? "").trim();
6
- if (normalized === "" || seen.has(normalized))
7
- continue;
8
- seen.add(normalized);
9
- out.push(normalized);
10
- }
11
- return out;
12
- }
13
- function resolveWindow(raw, label) {
14
- const candidate = (raw ?? globalThis.window);
15
- if (candidate == null) {
16
- throw new Error(`${label} is not available in this environment`);
17
- }
18
- return candidate;
19
- }
20
- function getServiceWorker(targetWindow) {
21
- return targetWindow.navigator?.serviceWorker ?? null;
22
- }
23
- function parseRepairAttemptFromHref(href, queryKey) {
1
+ function serviceWorkerContainer(target) {
24
2
  try {
25
- const url = new URL(href);
26
- const raw = String(url.searchParams.get(queryKey) ?? "").trim();
27
- const n = raw === "" ? 0 : Number(raw);
28
- if (!Number.isFinite(n) || n < 0)
29
- return 0;
30
- return Math.min(9, Math.floor(n));
3
+ return target.navigator?.serviceWorker;
31
4
  }
32
5
  catch {
33
- return 0;
6
+ return undefined;
34
7
  }
35
8
  }
36
- function buildHrefWithRepairAttempt(href, queryKey, attempt) {
37
- const url = new URL(href);
38
- url.searchParams.set(queryKey, String(Math.max(0, Math.floor(attempt))));
39
- return url.toString();
40
- }
41
- function isServiceWorkerScriptPathSuffix(raw, suffix) {
42
- const script = String(raw ?? "").trim();
43
- const wanted = String(suffix ?? "").trim();
44
- if (script === "" || wanted === "")
9
+ function scriptMatches(scriptURL, suffix) {
10
+ if (scriptURL === undefined || scriptURL === "")
45
11
  return false;
46
12
  try {
47
- return new URL(script).pathname.endsWith(wanted);
13
+ return new URL(scriptURL).pathname.endsWith(suffix);
48
14
  }
49
15
  catch {
50
- return script.endsWith(wanted);
16
+ return scriptURL.endsWith(suffix);
51
17
  }
52
18
  }
53
- async function waitForControllerSuffix(targetWindow, suffix, timeoutMs) {
54
- const sw = getServiceWorker(targetWindow);
55
- if (sw == null)
56
- return false;
57
- const isMatch = () => isServiceWorkerScriptPathSuffix(String(sw.controller?.scriptURL ?? ""), suffix);
58
- if (isMatch())
59
- return true;
60
- const ms = Math.max(0, Math.floor(timeoutMs));
61
- return await new Promise((resolve) => {
62
- let done = false;
63
- let timer = null;
64
- const finish = (ok) => {
65
- if (done)
66
- return;
67
- done = true;
68
- if (timer != null)
69
- targetWindow.clearTimeout(timer);
70
- sw.removeEventListener?.("controllerchange", onChange);
71
- resolve(ok);
72
- };
73
- const onChange = () => {
74
- if (isMatch())
75
- finish(true);
76
- };
77
- sw.addEventListener?.("controllerchange", onChange);
78
- if (isMatch()) {
79
- finish(true);
80
- return;
81
- }
82
- if (ms > 0) {
83
- timer = targetWindow.setTimeout(() => finish(isMatch()), ms);
84
- }
85
- else {
86
- finish(isMatch());
87
- }
88
- });
89
- }
90
- async function uninstallConflictingServiceWorkers(targetWindow, conflicts) {
91
- if (conflicts?.uninstallOnMismatch === false)
92
- return;
93
- const sw = getServiceWorker(targetWindow);
94
- if (sw == null || typeof sw.getRegistrations !== "function")
19
+ async function removeConflicts(container, expected, policy) {
20
+ if (policy?.uninstallOnMismatch === false || typeof container.getRegistrations !== "function")
95
21
  return;
96
- const keepSuffixes = dedupeStrings(conflicts?.keepScriptPathSuffixes ?? []);
97
- const regs = await sw.getRegistrations();
98
- for (const reg of regs) {
99
- const script = String(reg?.active?.scriptURL ?? reg?.waiting?.scriptURL ?? reg?.installing?.scriptURL ?? "").trim();
100
- if (script === "")
101
- continue;
102
- let shouldKeep = false;
103
- for (const suffix of keepSuffixes) {
104
- if (isServiceWorkerScriptPathSuffix(script, suffix)) {
105
- shouldKeep = true;
106
- break;
107
- }
108
- }
109
- if (shouldKeep)
110
- continue;
111
- try {
112
- await reg.unregister?.();
113
- }
114
- catch {
115
- // Best effort cleanup.
22
+ const keep = [expected, ...(policy?.keepScriptPathSuffixes ?? [])];
23
+ for (const registration of await container.getRegistrations()) {
24
+ const script = registration.active?.scriptURL ?? registration.waiting?.scriptURL ?? registration.installing?.scriptURL;
25
+ if (script !== undefined && !keep.some((suffix) => scriptMatches(script, suffix))) {
26
+ await registration.unregister().catch(() => false);
116
27
  }
117
28
  }
118
29
  }
119
- function triggerRepairNavigation(navigationWindow, repair, attempt) {
120
- const queryKey = String(repair?.queryKey ?? "_flowersec_sw_repair").trim() || "_flowersec_sw_repair";
121
- const maxAttempts = Math.max(0, Math.floor(repair?.maxAttempts ?? 2));
122
- const strategy = repair?.strategy ?? "replace";
123
- const hrefAttempt = parseRepairAttemptFromHref(navigationWindow.location.href, queryKey);
124
- const effectiveAttempt = Math.max(attempt, hrefAttempt);
125
- if (effectiveAttempt >= maxAttempts)
126
- return false;
127
- if (strategy === "reload") {
128
- navigationWindow.location.reload();
129
- return true;
30
+ function repair(target, options) {
31
+ const key = options?.queryKey?.trim() || "_flowersec_sw_repair";
32
+ const maxAttempts = options?.maxAttempts ?? 2;
33
+ let url;
34
+ try {
35
+ url = new URL(target.location.href);
130
36
  }
131
- const next = buildHrefWithRepairAttempt(navigationWindow.location.href, queryKey, effectiveAttempt + 1);
132
- navigationWindow.location.replace(next);
133
- return true;
134
- }
135
- export function createServiceWorkerControllerGuard(opts) {
136
- const targetWindow = resolveWindow(opts.targetWindow, "targetWindow");
137
- const navigationWindow = resolveWindow(opts.navigationWindow ?? opts.targetWindow, "navigationWindow");
138
- const expectedScriptPathSuffix = String(opts.expectedScriptPathSuffix ?? "").trim();
139
- if (expectedScriptPathSuffix === "") {
140
- throw new Error("expectedScriptPathSuffix must be non-empty");
37
+ catch {
38
+ throw new Error("service worker controller repair URL is unavailable");
39
+ }
40
+ const current = Number(url.searchParams.get(key) ?? "0");
41
+ const attempt = Number.isSafeInteger(current) && current >= 0 ? current : 0;
42
+ if (attempt >= maxAttempts)
43
+ throw new Error("service worker controller mismatch persists");
44
+ if (options?.strategy === "reload") {
45
+ target.location.reload();
141
46
  }
142
- const controllerTimeoutMs = Math.max(0, Math.floor(opts.repair?.controllerTimeoutMs ?? 8_000));
143
- const monitorEnabled = opts.monitor?.enabled ?? true;
144
- const monitorThrottleMs = Math.max(0, Math.floor(opts.monitor?.throttleMs ?? 10_000));
47
+ else {
48
+ url.searchParams.set(key, String(attempt + 1));
49
+ target.location.replace(url.toString());
50
+ }
51
+ throw new Error("service worker controller repair navigation started");
52
+ }
53
+ export function createServiceWorkerControllerGuard(options) {
54
+ const target = options.targetWindow ?? globalThis.window;
55
+ const navigation = options.navigationWindow ?? target;
56
+ const expected = options.expectedScriptPathSuffix.trim();
57
+ if (expected === "")
58
+ throw new TypeError("expected service worker script suffix is required");
59
+ const container = serviceWorkerContainer(target);
145
60
  let disposed = false;
146
- let monitorHandler = null;
147
- let lastMonitorRepairAt = 0;
148
- let repairAttempts = 0;
61
+ let lastRepairAt = 0;
149
62
  const handleMismatch = async (stage) => {
150
- const actualScriptURL = String(getServiceWorker(targetWindow)?.controller?.scriptURL ?? "").trim();
151
- const ctx = {
152
- expectedScriptPathSuffix,
153
- actualScriptURL,
154
- stage,
155
- };
156
- const action = opts.onControllerMismatch?.(ctx);
157
- if (action === "ignore")
158
- return "ignored";
159
- await uninstallConflictingServiceWorkers(targetWindow, opts.conflicts);
160
- const repaired = triggerRepairNavigation(navigationWindow, opts.repair, repairAttempts);
161
- if (repaired)
162
- repairAttempts += 1;
163
- return repaired ? "repaired" : "skipped";
63
+ if (disposed || container === undefined)
64
+ throw new Error("service worker controller is unavailable");
65
+ const actual = container.controller?.scriptURL ?? "";
66
+ const context = { expectedScriptPathSuffix: expected, actualScriptURL: actual, stage };
67
+ if (options.onControllerMismatch?.(context) === "ignore")
68
+ return;
69
+ await removeConflicts(container, expected, options.conflicts);
70
+ repair(navigation, options.repair);
164
71
  };
165
- const attachMonitor = () => {
166
- if (!monitorEnabled || monitorHandler != null)
72
+ const onControllerChange = () => {
73
+ if (disposed || options.monitor?.enabled === false || scriptMatches(container?.controller?.scriptURL, expected))
167
74
  return;
168
- const currentSW = getServiceWorker(targetWindow);
169
- if (currentSW == null)
75
+ const now = Date.now();
76
+ const throttle = options.monitor?.throttleMs ?? 10_000;
77
+ if (now - lastRepairAt < throttle)
170
78
  return;
171
- monitorHandler = () => {
172
- const actualScriptURL = String(currentSW.controller?.scriptURL ?? "").trim();
173
- if (isServiceWorkerScriptPathSuffix(actualScriptURL, expectedScriptPathSuffix))
174
- return;
175
- const now = Date.now();
176
- if (monitorThrottleMs > 0 && now - lastMonitorRepairAt <= monitorThrottleMs)
177
- return;
178
- lastMonitorRepairAt = now;
179
- void handleMismatch("monitor");
180
- };
181
- currentSW.addEventListener?.("controllerchange", monitorHandler);
79
+ lastRepairAt = now;
80
+ void handleMismatch("monitor").catch(() => undefined);
182
81
  };
183
- return {
82
+ container?.addEventListener("controllerchange", onControllerChange);
83
+ return Object.freeze({
184
84
  ensure: async () => {
185
85
  if (disposed)
186
- throw new Error("controller guard is already disposed");
187
- if (getServiceWorker(targetWindow) == null) {
188
- throw new Error("service worker is not available in the target window");
189
- }
190
- const ok = await waitForControllerSuffix(targetWindow, expectedScriptPathSuffix, controllerTimeoutMs);
191
- if (!ok) {
192
- const outcome = await handleMismatch("ensure");
193
- if (outcome !== "ignored") {
194
- throw new Error("Proxy Service Worker is installed but not controlling the target window");
195
- }
86
+ throw new Error("service worker controller guard is disposed");
87
+ if (container === undefined)
88
+ throw new Error("service worker controller is unavailable");
89
+ if (scriptMatches(container.controller?.scriptURL, expected))
196
90
  return;
197
- }
198
- attachMonitor();
91
+ const timeoutMs = options.repair?.controllerTimeoutMs ?? 8_000;
92
+ const matched = await new Promise((resolve) => {
93
+ const onChange = () => {
94
+ if (!scriptMatches(container.controller?.scriptURL, expected))
95
+ return;
96
+ cleanup();
97
+ resolve(true);
98
+ };
99
+ const cleanup = () => {
100
+ clearTimeout(timer);
101
+ container.removeEventListener("controllerchange", onChange);
102
+ };
103
+ container.addEventListener("controllerchange", onChange);
104
+ const timer = setTimeout(() => { cleanup(); resolve(scriptMatches(container.controller?.scriptURL, expected)); }, timeoutMs);
105
+ });
106
+ if (!matched)
107
+ await handleMismatch("ensure");
199
108
  },
200
109
  dispose: () => {
201
110
  if (disposed)
202
111
  return;
203
112
  disposed = true;
204
- if (monitorHandler != null) {
205
- getServiceWorker(targetWindow)?.removeEventListener?.("controllerchange", monitorHandler);
206
- }
207
- monitorHandler = null;
113
+ container?.removeEventListener("controllerchange", onControllerChange);
208
114
  },
209
- };
115
+ });
210
116
  }
@@ -1 +1,3 @@
1
- export declare function disableUpstreamServiceWorkerRegister(): void;
1
+ export declare function disableUpstreamServiceWorkerRegister(): Readonly<{
2
+ restore(): void;
3
+ }>;
@@ -1,23 +1,25 @@
1
- // disableUpstreamServiceWorkerRegister blocks upstream apps from registering their own Service Worker.
2
- //
3
- // This is required for runtime-mode proxying where a proxy SW must control the app scope.
4
1
  export function disableUpstreamServiceWorkerRegister() {
2
+ const serviceWorker = globalThis.navigator?.serviceWorker;
3
+ if (serviceWorker === undefined || typeof serviceWorker.register !== "function")
4
+ return Object.freeze({ restore: () => undefined });
5
+ const original = serviceWorker.register.bind(serviceWorker);
6
+ const replacement = async () => {
7
+ throw new Error("upstream service worker registration is disabled by the Flowersec proxy runtime");
8
+ };
5
9
  try {
6
- const sw = globalThis.navigator?.serviceWorker;
7
- if (!sw || typeof sw.register !== "function")
8
- return;
9
- const blocked = () => {
10
- throw new Error("service worker register is disabled by flowersec-proxy runtime");
11
- };
12
- // Best-effort. Some environments may not allow overriding the property.
13
- try {
14
- sw.register = blocked;
15
- }
16
- catch {
17
- // Ignore.
18
- }
10
+ Object.defineProperty(serviceWorker, "register", { configurable: true, value: replacement });
19
11
  }
20
12
  catch {
21
- // Ignore.
13
+ return Object.freeze({ restore: () => undefined });
22
14
  }
15
+ return Object.freeze({
16
+ restore: () => {
17
+ try {
18
+ Object.defineProperty(serviceWorker, "register", { configurable: true, value: original });
19
+ }
20
+ catch {
21
+ // Best effort restoration during page teardown.
22
+ }
23
+ },
24
+ });
23
25
  }
@@ -1,16 +1,17 @@
1
- export * from "./constants.js";
2
- export * from "./types.js";
3
- export * from "./cookieJar.js";
4
- export type { ProxyPresetInput, ProxyPresetLimits, ProxyPresetManifest, ResolvedProxyPreset } from "./preset.js";
5
- export { DEFAULT_PROXY_PRESET_MANIFEST, assertProxyPresetManifest, resolveProxyPreset } from "./preset.js";
6
- export * from "./runtime.js";
7
- export * from "./serviceWorker.js";
1
+ export { PROXY_RUNTIME_SCOPE, assertProxyRuntimeScope } from "./scope.js";
2
+ export { createProxyRuntime, ensureServiceWorkerRuntimeRegistered } from "./runtime.js";
3
+ export type { EnsureServiceWorkerRuntimeRegisteredOptions } from "./runtime.js";
4
+ export { createProxyServiceWorkerScript } from "./serviceWorker.js";
5
+ export type { ProxyServiceWorkerInjectHTMLOptions, ProxyServiceWorkerPassthroughOptions, ProxyServiceWorkerScriptOptions, } from "./serviceWorker.js";
8
6
  export { registerServiceWorkerAndEnsureControl } from "./registerServiceWorker.js";
9
- export * from "./integration.js";
10
- export * from "./controllerGuard.js";
11
- export * from "./bootstrap.js";
12
- export * from "./runtimeScope.js";
13
- export * from "./controllerWindow.js";
14
- export * from "./appWindow.js";
15
- export * from "./wsPatch.js";
16
- export * from "./disableUpstreamServiceWorkerRegister.js";
7
+ export type { RegisterServiceWorkerOptions } from "./registerServiceWorker.js";
8
+ export { createServiceWorkerControllerGuard } from "./controllerGuard.js";
9
+ export type { ServiceWorkerControllerGuardConflictPolicy, ServiceWorkerControllerGuardHandle, ServiceWorkerControllerGuardMismatchContext, ServiceWorkerControllerGuardMonitorOptions, ServiceWorkerControllerGuardOptions, ServiceWorkerControllerGuardRepairOptions, } from "./controllerGuard.js";
10
+ export { registerProxyAppWindow, registerProxyAppWindowWithServiceWorkerControl, registerProxyControllerWindow, } from "./windowBridge.js";
11
+ export type { ProxyAppServiceWorkerControlOptions, ProxyAppWindowHandle, ProxyControllerWindowHandle, RegisterProxyAppWindowOptions, RegisterProxyAppWindowWithServiceWorkerControlOptions, RegisterProxyControllerWindowOptions, } from "./windowBridge.js";
12
+ export { installWebSocketPatch } from "./wsPatch.js";
13
+ export type { WebSocketPatchOptions } from "./wsPatch.js";
14
+ export { disableUpstreamServiceWorkerRegister } from "./disableUpstreamServiceWorkerRegister.js";
15
+ export { connectProxyBrowser, connectProxyControllerBrowser, } from "./integration.js";
16
+ export type { ProxyBrowserConnectOptions, ProxyBrowserHandle, ProxyControllerBrowserConnectOptions, ProxyControllerBrowserHandle, } from "./integration.js";
17
+ export type { ProxyFetchRequest, ProxyHeader, ProxyRuntime, ProxyRuntimeControllerBridgeScope, ProxyRuntimeLimits, ProxyRuntimeOptions, ProxyRuntimePathPolicy, ProxyRuntimeScopeLimits, ProxyRuntimeScope, ProxyRuntimeServiceWorkerScope, } from "./types.js";
@@ -1,15 +1,9 @@
1
- export * from "./constants.js";
2
- export * from "./types.js";
3
- export * from "./cookieJar.js";
4
- export { DEFAULT_PROXY_PRESET_MANIFEST, assertProxyPresetManifest, resolveProxyPreset } from "./preset.js";
5
- export * from "./runtime.js";
6
- export * from "./serviceWorker.js";
1
+ export { PROXY_RUNTIME_SCOPE, assertProxyRuntimeScope } from "./scope.js";
2
+ export { createProxyRuntime, ensureServiceWorkerRuntimeRegistered } from "./runtime.js";
3
+ export { createProxyServiceWorkerScript } from "./serviceWorker.js";
7
4
  export { registerServiceWorkerAndEnsureControl } from "./registerServiceWorker.js";
8
- export * from "./integration.js";
9
- export * from "./controllerGuard.js";
10
- export * from "./bootstrap.js";
11
- export * from "./runtimeScope.js";
12
- export * from "./controllerWindow.js";
13
- export * from "./appWindow.js";
14
- export * from "./wsPatch.js";
15
- export * from "./disableUpstreamServiceWorkerRegister.js";
5
+ export { createServiceWorkerControllerGuard } from "./controllerGuard.js";
6
+ export { registerProxyAppWindow, registerProxyAppWindowWithServiceWorkerControl, registerProxyControllerWindow, } from "./windowBridge.js";
7
+ export { installWebSocketPatch } from "./wsPatch.js";
8
+ export { disableUpstreamServiceWorkerRegister } from "./disableUpstreamServiceWorkerRegister.js";
9
+ export { connectProxyBrowser, connectProxyControllerBrowser, } from "./integration.js";
@@ -1,77 +1,29 @@
1
- import type { Client } from "../client.js";
2
- import { type ProxyPresetInput, type ResolvedProxyPreset } from "./preset.js";
3
- import { type ProxyRuntime, type ProxyRuntimePathPolicy } from "./runtime.js";
4
- import { type ProxyServiceWorkerScriptOptions } from "./serviceWorker.js";
5
- export type ProxyIntegrationMonitorOptions = Readonly<{
6
- enabled?: boolean;
7
- throttleMs?: number;
8
- }>;
9
- export type ProxyIntegrationRepairOptions = Readonly<{
10
- queryKey?: string;
11
- maxAttempts?: number;
12
- controllerTimeoutMs?: number;
13
- strategy?: "replace" | "reload";
14
- }>;
15
- export type ProxyServiceWorkerConflictPolicy = Readonly<{
16
- keepScriptPathSuffixes?: readonly string[];
17
- uninstallOnMismatch?: boolean;
18
- }>;
19
- export type ProxyIntegrationServiceWorkerOptions = Readonly<{
20
- scriptUrl: string;
21
- scope?: string;
22
- expectedScriptPathSuffix?: string;
23
- repair?: ProxyIntegrationRepairOptions;
24
- monitor?: ProxyIntegrationMonitorOptions;
25
- conflicts?: ProxyServiceWorkerConflictPolicy;
26
- }>;
27
- export type RegisterProxyIntegrationOptions = Readonly<{
28
- client: Client;
29
- preset?: ProxyPresetInput;
30
- runtimeGlobalKey?: string;
31
- runtime?: Readonly<{
32
- maxJsonFrameBytes?: number;
33
- maxChunkBytes?: number;
34
- maxBodyBytes?: number;
35
- maxWsFrameBytes?: number;
36
- maxWsBufferedAmountBytes?: number;
37
- maxConcurrentHttpStreams?: number;
38
- maxQueuedHttpRequests?: number;
39
- maxQueuedHttpBodyBytes?: number;
40
- timeoutMs?: number;
41
- pathPolicy?: ProxyRuntimePathPolicy;
42
- externalOrigin?: string;
43
- runtimeRegistrationToken?: string;
1
+ import { type SessionOptions } from "../browser/connectSession.js";
2
+ import type { ArtifactLease } from "../public/artifactLease.js";
3
+ import type { Session } from "../public/contract.js";
4
+ import type { ProxyRuntime, ProxyRuntimeOptions } from "./types.js";
5
+ import { type ProxyControllerWindowHandle, type RegisterProxyControllerWindowOptions } from "./windowBridge.js";
6
+ export type ProxyBrowserConnectOptions = Readonly<{
7
+ connect?: SessionOptions;
8
+ runtime?: Omit<ProxyRuntimeOptions, "session">;
9
+ serviceWorker?: Readonly<{
10
+ scriptUrl: string;
11
+ scope?: string;
12
+ repairQueryKey?: string;
13
+ maxRepairAttempts?: number;
14
+ controllerTimeoutMs?: number;
44
15
  }>;
45
- serviceWorker: ProxyIntegrationServiceWorkerOptions;
46
- plugins?: readonly ProxyIntegrationPlugin[];
47
16
  }>;
48
- export type ProxyIntegrationContext = Readonly<{
17
+ export type ProxyBrowserHandle = Readonly<{
18
+ session: Session;
49
19
  runtime: ProxyRuntime;
50
- options: RegisterProxyIntegrationOptions;
51
- preset: ResolvedProxyPreset;
20
+ dispose(): Promise<void>;
52
21
  }>;
53
- export type ControllerMismatchContext = Readonly<{
54
- expectedScriptPathSuffix: string;
55
- actualScriptURL: string;
56
- stage: "register" | "monitor";
57
- }>;
58
- export type ProxyIntegrationPlugin = Readonly<{
59
- name: string;
60
- mutateOptions?: (opts: RegisterProxyIntegrationOptions) => RegisterProxyIntegrationOptions;
61
- extendServiceWorkerScriptOptions?: (opts: ProxyServiceWorkerScriptOptions) => ProxyServiceWorkerScriptOptions;
62
- serviceWorkerConflictPolicy?: ProxyServiceWorkerConflictPolicy;
63
- forwardFetchMessageTypes?: readonly string[];
64
- onRegistered?: (ctx: ProxyIntegrationContext) => void | Promise<void>;
65
- onControllerMismatch?: (ctx: ControllerMismatchContext) => "repair" | "ignore" | void;
66
- onDisposed?: () => void | Promise<void>;
67
- }>;
68
- export type ProxyIntegrationHandle = Readonly<{
69
- runtime: ProxyRuntime;
70
- dispose: () => Promise<void>;
22
+ export declare function connectProxyBrowser(lease: ArtifactLease, options?: ProxyBrowserConnectOptions): Promise<ProxyBrowserHandle>;
23
+ export type ProxyControllerBrowserConnectOptions = ProxyBrowserConnectOptions & Readonly<{
24
+ controller: Omit<RegisterProxyControllerWindowOptions, "runtime">;
71
25
  }>;
72
- export type CreateProxyIntegrationServiceWorkerScriptOptions = Readonly<{
73
- baseOptions?: ProxyServiceWorkerScriptOptions;
74
- plugins?: readonly ProxyIntegrationPlugin[];
26
+ export type ProxyControllerBrowserHandle = ProxyBrowserHandle & Readonly<{
27
+ controller: ProxyControllerWindowHandle;
75
28
  }>;
76
- export declare function createProxyIntegrationServiceWorkerScript(opts?: CreateProxyIntegrationServiceWorkerScriptOptions): string;
77
- export declare function registerProxyIntegration(input: RegisterProxyIntegrationOptions): Promise<ProxyIntegrationHandle>;
29
+ export declare function connectProxyControllerBrowser(lease: ArtifactLease, options: ProxyControllerBrowserConnectOptions): Promise<ProxyControllerBrowserHandle>;