@floegence/floe-webapp-boot 0.44.1 → 0.45.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.
@@ -1,4 +1,5 @@
1
1
  import type { ArtifactSource, ConnectionSnapshot } from '@floegence/flowersec-core';
2
+ import type { PrivateLoopbackArtifactSourceV1 } from '@floegence/flowersec-core/browser';
2
3
  import { ConnectedAcquisition } from './acquisition';
3
4
  import { ProxyBootstrapOwner } from './proxy-bootstrap';
4
5
  export interface AcquisitionConnectionLifecycle {
@@ -9,4 +10,4 @@ export type AcquisitionConnectionLifecycleOptions = Readonly<{
9
10
  proxyBootstrap?: ProxyBootstrapOwner;
10
11
  onConnected?: (acquisition: ConnectedAcquisition) => void;
11
12
  }>;
12
- export declare function createAcquisitionConnectionLifecycle(source: ArtifactSource, options?: AcquisitionConnectionLifecycleOptions): AcquisitionConnectionLifecycle;
13
+ export declare function createAcquisitionConnectionLifecycle(source: ArtifactSource | PrivateLoopbackArtifactSourceV1, options?: AcquisitionConnectionLifecycleOptions): AcquisitionConnectionLifecycle;
@@ -1,5 +1,5 @@
1
1
  import { type ArtifactLease, type ArtifactSource, type ConnectionSnapshot, type JsonValue, type Session } from '@floegence/flowersec-core';
2
- import type { ConnectionControllerOptions, SessionOptions } from '@floegence/flowersec-core/browser';
2
+ import type { ConnectionControllerOptions, PrivateLoopbackArtifactLeaseV1, PrivateLoopbackArtifactSourceV1, SessionOptions } from '@floegence/flowersec-core/browser';
3
3
  import { type ProxyRuntimeScope } from '@floegence/flowersec-core/proxy';
4
4
  export type CriticalScopeProjectionV1 = Readonly<{
5
5
  scope: 'proxy.runtime';
@@ -70,6 +70,7 @@ export declare class IsolatedOneShotAcquisition {
70
70
  static create(): IsolatedOneShotAcquisition;
71
71
  static assertAuthentic(value: IsolatedOneShotAcquisition): void;
72
72
  }
73
+ type AcquisitionSource = ArtifactSource | PrivateLoopbackArtifactSourceV1;
73
74
  export type ConnectedAcquisitionDetails = Readonly<{
74
75
  session: Session;
75
76
  scope: ProxyRuntimeScope;
@@ -81,10 +82,11 @@ type MaterializeOptions = Readonly<{
81
82
  validateSpendBinding: ValidateSpendBinding;
82
83
  expectedConsumer: 'trusted' | 'isolated';
83
84
  }>;
84
- export declare function registerAcquisitionSource(source: ArtifactSource): void;
85
+ export declare function registerAcquisitionSource(source: AcquisitionSource): void;
85
86
  export declare function materializeAcquisitionForSource(source: ArtifactSource, value: unknown, options: MaterializeOptions): Promise<ArtifactLease>;
86
- export declare function synchronizeAcquisitionSourceSnapshot(source: ArtifactSource, snapshot: ConnectionSnapshot): ConnectedAcquisition | null;
87
- export declare function clearAcquisitionSource(source: ArtifactSource): void;
87
+ export declare function materializePrivateLoopbackAcquisitionForSource(source: PrivateLoopbackArtifactSourceV1, value: unknown, options: MaterializeOptions): Promise<PrivateLoopbackArtifactLeaseV1>;
88
+ export declare function synchronizeAcquisitionSourceSnapshot(source: AcquisitionSource, snapshot: ConnectionSnapshot): ConnectedAcquisition | null;
89
+ export declare function clearAcquisitionSource(source: AcquisitionSource): void;
88
90
  export declare function connectedAcquisitionDetails(acquisition: ConnectedAcquisition): ConnectedAcquisitionDetails;
89
91
  export type IsolatedHandoffValidationContext = Readonly<{
90
92
  envPublicId: string;
@@ -1,9 +1,9 @@
1
- import { parseArtifact as R, createArtifactLease as $ } from "@floegence/flowersec-core";
2
- import { assertProxyRuntimeScope as C } from "@floegence/flowersec-core/proxy";
3
- const j = 32, F = 16384, L = "#redeven=";
4
- class n extends Error {
5
- constructor(i) {
6
- super(`Floe acquisition failed (code=${i})`), this.code = i, this.name = "AcquisitionError";
1
+ import { createArtifactLease as I, parseArtifact as T } from "@floegence/flowersec-core";
2
+ import { assertProxyRuntimeScope as F } from "@floegence/flowersec-core/proxy";
3
+ const j = 32, C = 16384, P = "#redeven=";
4
+ class r extends Error {
5
+ constructor(t) {
6
+ super(`Floe acquisition failed (code=${t})`), this.code = t, this.name = "AcquisitionError";
7
7
  }
8
8
  }
9
9
  class h {
@@ -14,8 +14,8 @@ class h {
14
14
  static create() {
15
15
  return new h();
16
16
  }
17
- static assertAuthentic(i) {
18
- i.#e;
17
+ static assertAuthentic(t) {
18
+ t.#e;
19
19
  }
20
20
  }
21
21
  class m {
@@ -26,203 +26,266 @@ class m {
26
26
  static create() {
27
27
  return new m();
28
28
  }
29
- static assertAuthentic(i) {
30
- i.#e;
29
+ static assertAuthentic(t) {
30
+ t.#e;
31
31
  }
32
32
  }
33
- const g = /* @__PURE__ */ new WeakMap(), S = /* @__PURE__ */ new WeakMap(), z = /* @__PURE__ */ new WeakMap(), O = /* @__PURE__ */ new Set();
34
- function X(e) {
35
- if (g.has(e)) throw new n("duplicate_acquisition_source");
33
+ const g = /* @__PURE__ */ new WeakMap(), A = /* @__PURE__ */ new WeakMap(), E = /* @__PURE__ */ new WeakMap(), z = /* @__PURE__ */ new Set();
34
+ function Y(e) {
35
+ if (g.has(e)) throw new r("duplicate_acquisition_source");
36
36
  g.set(e, { pending: [] });
37
37
  }
38
- async function Y(e, i, t) {
39
- const r = g.get(e);
40
- if (r === void 0) throw new n("invalid_acquisition_source");
41
- const c = await x(i, t);
42
- return D(c, t.commitSpend, (o) => {
43
- r.pending.push(o);
44
- }, (o) => {
45
- r.pending = r.pending.filter((a) => a !== o);
46
- });
38
+ async function K(e, t, i) {
39
+ const n = g.get(e);
40
+ if (n === void 0) throw new r("invalid_acquisition_source");
41
+ const o = await S(t, i, T);
42
+ return O(
43
+ o,
44
+ I,
45
+ i.commitSpend,
46
+ (c) => {
47
+ n.pending.push(c);
48
+ },
49
+ (c) => {
50
+ n.pending = n.pending.filter((a) => a !== c);
51
+ }
52
+ );
47
53
  }
48
- function K(e, i) {
49
- const t = g.get(e);
50
- if (t === void 0) return null;
51
- if (i.state !== "connected" || i.currentSession === void 0)
52
- return (i.state === "idle" || i.state === "waiting" || i.state === "failed" || i.state === "closed") && (t.pending = [], t.connected = void 0, t.connectedSession = void 0), null;
53
- if (t.connected !== void 0 && t.connectedSession === i.currentSession) return t.connected;
54
- const r = t.pending.filter((a) => a.committed);
55
- if (r.length !== 1 || t.pending.length !== 1)
56
- throw t.pending = [], new n("connected_acquisition_mismatch");
57
- const c = r[0];
58
- if (c === void 0) throw new n("connected_acquisition_mismatch");
59
- const o = h.create();
60
- return S.set(o, Object.freeze({
61
- session: i.currentSession,
62
- scope: c.scope,
63
- bindingIdentity: c.bindingIdentity,
64
- attempt: i.attempt
65
- })), t.pending = [], t.connected = o, t.connectedSession = i.currentSession, o;
54
+ async function Q(e, t, i) {
55
+ const n = g.get(e);
56
+ if (n === void 0) throw new r("invalid_acquisition_source");
57
+ const o = await import("@floegence/flowersec-core/browser"), c = await S(
58
+ t,
59
+ i,
60
+ o.parsePrivateLoopbackArtifactV1
61
+ );
62
+ return O(
63
+ c,
64
+ o.createPrivateLoopbackArtifactLeaseV1,
65
+ i.commitSpend,
66
+ (a) => {
67
+ n.pending.push(a);
68
+ },
69
+ (a) => {
70
+ n.pending = n.pending.filter((d) => d !== a);
71
+ }
72
+ );
66
73
  }
67
- function Q(e) {
74
+ function ee(e, t) {
68
75
  const i = g.get(e);
69
- i !== void 0 && (i.pending = [], i.connected = void 0, i.connectedSession = void 0);
76
+ if (i === void 0) return null;
77
+ if (t.state !== "connected" || t.currentSession === void 0)
78
+ return (t.state === "idle" || t.state === "waiting" || t.state === "failed" || t.state === "closed") && (i.pending = [], i.connected = void 0, i.connectedSession = void 0), null;
79
+ if (i.connected !== void 0 && i.connectedSession === t.currentSession)
80
+ return i.connected;
81
+ const n = i.pending.filter((a) => a.committed);
82
+ if (n.length !== 1 || i.pending.length !== 1)
83
+ throw i.pending = [], new r("connected_acquisition_mismatch");
84
+ const o = n[0];
85
+ if (o === void 0) throw new r("connected_acquisition_mismatch");
86
+ const c = h.create();
87
+ return A.set(
88
+ c,
89
+ Object.freeze({
90
+ session: t.currentSession,
91
+ scope: o.scope,
92
+ bindingIdentity: o.bindingIdentity,
93
+ attempt: t.attempt
94
+ })
95
+ ), i.pending = [], i.connected = c, i.connectedSession = t.currentSession, c;
70
96
  }
71
- function ee(e) {
97
+ function te(e) {
98
+ const t = g.get(e);
99
+ t !== void 0 && (t.pending = [], t.connected = void 0, t.connectedSession = void 0);
100
+ }
101
+ function ie(e) {
72
102
  h.assertAuthentic(e);
73
- const i = S.get(e);
74
- if (i === void 0) throw new n("invalid_connected_acquisition");
75
- return i;
103
+ const t = A.get(e);
104
+ if (t === void 0) throw new r("invalid_connected_acquisition");
105
+ return t;
76
106
  }
77
- async function te(e) {
78
- const i = e.rawHandoff, t = typeof i != "string" || Z(`${L}${i}`) > F;
79
- let r = !1;
107
+ async function ne(e) {
108
+ const t = e.rawHandoff, i = typeof t != "string" || W(`${P}${t}`) > C;
109
+ let n = !1;
80
110
  try {
81
- r = e.clearSensitiveLocation() === !0;
111
+ n = e.clearSensitiveLocation() === !0;
82
112
  } catch {
83
- r = !1;
113
+ n = !1;
84
114
  }
85
- if (!r)
86
- throw e.navigateToLauncher(), new n("isolated_location_clear_failed");
87
- if (t) throw new n("isolated_handoff_too_large");
88
- const c = y(i, "invalid_isolated_handoff"), o = await V(c);
89
- if (O.has(o)) throw new n("isolated_handoff_consumed");
90
- O.add(o);
115
+ if (!n)
116
+ throw e.navigateToLauncher(), new r("isolated_location_clear_failed");
117
+ if (i) throw new r("isolated_handoff_too_large");
118
+ const o = y(t, "invalid_isolated_handoff"), c = await J(o);
119
+ if (z.has(c))
120
+ throw new r("isolated_handoff_consumed");
121
+ z.add(c);
91
122
  let a;
92
123
  try {
93
- a = JSON.parse(new TextDecoder("utf-8", { fatal: !0 }).decode(c));
124
+ a = JSON.parse(new TextDecoder("utf-8", { fatal: !0 }).decode(o));
94
125
  } catch {
95
- throw new n("invalid_isolated_handoff");
126
+ throw new r("invalid_isolated_handoff");
96
127
  }
97
- const _ = P(a, e.validationContext), u = await x(_.acquisition, {
98
- commitSpend: e.commitSpend,
99
- expectedConsumer: "isolated",
100
- validateSpendBinding: (d) => (k(_, d, e.validationContext), e.validationContext.validateTargetBinding(d.targetBinding), `${d.artifactDigestB64u}.${d.projectionDigestB64u}`)
101
- });
102
- if (u.scope.appBasePath !== _.app_path) throw new n("isolated_app_path_mismatch");
103
- if (u.scope.mode === "controller_bridge") {
104
- const d = u.scope.controllerBridge.allowedOrigins;
105
- if (d.length !== 1 || d[0] !== _.app_origin)
106
- throw new n("isolated_allowed_origins_mismatch");
128
+ const d = V(a, e.validationContext), p = await S(
129
+ d.acquisition,
130
+ {
131
+ commitSpend: e.commitSpend,
132
+ expectedConsumer: "isolated",
133
+ validateSpendBinding: (s) => (N(d, s, e.validationContext), e.validationContext.validateTargetBinding(s.targetBinding), `${s.artifactDigestB64u}.${s.projectionDigestB64u}`)
134
+ },
135
+ T
136
+ );
137
+ if (p.scope.appBasePath !== d.app_path)
138
+ throw new r("isolated_app_path_mismatch");
139
+ if (p.scope.mode === "controller_bridge") {
140
+ const s = p.scope.controllerBridge.allowedOrigins;
141
+ if (s.length !== 1 || s[0] !== d.app_origin)
142
+ throw new r("isolated_allowed_origins_mismatch");
107
143
  }
108
- let s;
109
- const l = D(u, e.commitSpend, (d) => {
110
- s = d;
111
- }, () => {
112
- });
113
- if (s === void 0 || s.lease !== l) throw new n("isolated_materialization_failed");
114
- const p = m.create();
115
- return z.set(p, { pending: s, state: "ready" }), p;
144
+ let u;
145
+ const l = O(
146
+ p,
147
+ I,
148
+ e.commitSpend,
149
+ (s) => {
150
+ u = s;
151
+ },
152
+ () => {
153
+ }
154
+ );
155
+ if (u === void 0 || u.lease !== l)
156
+ throw new r("isolated_materialization_failed");
157
+ const _ = m.create();
158
+ return E.set(_, { pending: u, state: "ready" }), _;
116
159
  }
117
- async function ie(e, i = {}) {
160
+ async function re(e, t = {}) {
118
161
  m.assertAuthentic(e);
119
- const t = z.get(e);
120
- if (t === void 0 || t.state !== "ready") throw new n("isolated_acquisition_consumed");
121
- t.state = "connecting";
162
+ const i = E.get(e);
163
+ if (i === void 0 || i.state !== "ready")
164
+ throw new r("isolated_acquisition_consumed");
165
+ i.state = "connecting";
122
166
  try {
123
- const { connect: r } = await import("@floegence/flowersec-core/browser"), c = await r(t.pending.lease, i);
124
- if (!t.pending.committed)
125
- throw await c.close().catch(() => {
126
- }), new n("isolated_spend_not_committed");
127
- const o = h.create();
128
- return S.set(o, Object.freeze({
129
- session: c,
130
- scope: t.pending.scope,
131
- bindingIdentity: t.pending.bindingIdentity,
132
- attempt: 1
133
- })), t.state = "consumed", o;
134
- } catch (r) {
135
- throw t.state = "consumed", r;
167
+ const { connect: n } = await import("@floegence/flowersec-core/browser"), o = await n(i.pending.lease, t);
168
+ if (!i.pending.committed)
169
+ throw await o.close().catch(() => {
170
+ }), new r("isolated_spend_not_committed");
171
+ const c = h.create();
172
+ return A.set(
173
+ c,
174
+ Object.freeze({
175
+ session: o,
176
+ scope: i.pending.scope,
177
+ bindingIdentity: i.pending.bindingIdentity,
178
+ attempt: 1
179
+ })
180
+ ), i.state = "consumed", c;
181
+ } catch (n) {
182
+ throw i.state = "consumed", n;
136
183
  }
137
184
  }
138
- async function x(e, i) {
139
- const t = w(e, ["v", "connect_artifact", "critical_scope_projection_json", "spend_scope"], "invalid_acquisition_envelope");
140
- if (t.v !== 1 || typeof t.connect_artifact != "string" || t.connect_artifact.length === 0 || typeof t.critical_scope_projection_json != "string" || t.critical_scope_projection_json.length === 0)
141
- throw new n("invalid_acquisition_envelope");
142
- const r = U(t.spend_scope, i.expectedConsumer), c = new TextEncoder().encode(t.connect_artifact), o = new TextEncoder().encode(t.critical_scope_projection_json);
143
- await q(c, r.artifact_digest_b64u, "artifact_digest_mismatch"), await q(o, r.projection_digest_b64u, "projection_digest_mismatch");
144
- let a;
185
+ async function S(e, t, i) {
186
+ const n = w(
187
+ e,
188
+ ["v", "connect_artifact", "critical_scope_projection_json", "spend_scope"],
189
+ "invalid_acquisition_envelope"
190
+ );
191
+ if (n.v !== 1 || typeof n.connect_artifact != "string" || n.connect_artifact.length === 0 || typeof n.critical_scope_projection_json != "string" || n.critical_scope_projection_json.length === 0)
192
+ throw new r("invalid_acquisition_envelope");
193
+ const o = k(n.spend_scope, t.expectedConsumer), c = new TextEncoder().encode(n.connect_artifact), a = new TextEncoder().encode(n.critical_scope_projection_json);
194
+ await D(c, o.artifact_digest_b64u, "artifact_digest_mismatch"), await D(
195
+ a,
196
+ o.projection_digest_b64u,
197
+ "projection_digest_mismatch"
198
+ );
199
+ let d;
145
200
  try {
146
- a = JSON.parse(t.critical_scope_projection_json);
201
+ d = JSON.parse(n.critical_scope_projection_json);
147
202
  } catch {
148
- throw new n("invalid_critical_scope_projection");
203
+ throw new r("invalid_critical_scope_projection");
149
204
  }
150
- const _ = w(a, ["scope", "scope_version", "critical", "payload"], "invalid_critical_scope_projection");
151
- if (_.scope !== "proxy.runtime" || _.scope_version !== 2 || _.critical !== !0)
152
- throw new n("invalid_critical_scope_projection");
205
+ const p = w(
206
+ d,
207
+ ["scope", "scope_version", "critical", "payload"],
208
+ "invalid_critical_scope_projection"
209
+ );
210
+ if (p.scope !== "proxy.runtime" || p.scope_version !== 2 || p.critical !== !0)
211
+ throw new r("invalid_critical_scope_projection");
153
212
  let u;
154
213
  try {
155
- u = C(_.payload);
214
+ u = F(p.payload);
156
215
  } catch {
157
- throw new n("invalid_proxy_runtime_scope");
216
+ throw new r("invalid_proxy_runtime_scope");
158
217
  }
159
- let s;
218
+ let l;
160
219
  try {
161
- s = R(t.connect_artifact);
220
+ l = i(n.connect_artifact);
162
221
  } catch {
163
- throw new n("invalid_connect_artifact");
222
+ throw new r("invalid_connect_artifact");
164
223
  }
165
- const l = N(r), p = i.validateSpendBinding(l);
166
- if (p !== void 0 && (typeof p != "string" || p.trim() === "" || p !== p.trim()))
167
- throw new n("invalid_spend_binding_identity");
224
+ const _ = U(o), s = t.validateSpendBinding(_);
225
+ if (s !== void 0 && (typeof s != "string" || s.trim() === "" || s !== s.trim()))
226
+ throw new r("invalid_spend_binding_identity");
168
227
  return Object.freeze({
169
- artifact: s,
228
+ artifact: l,
170
229
  scope: u,
171
- binding: l,
172
- bindingIdentity: p ?? `${l.artifactDigestB64u}.${l.projectionDigestB64u}`,
173
- receipt: r.receipt
230
+ binding: _,
231
+ bindingIdentity: s ?? `${_.artifactDigestB64u}.${_.projectionDigestB64u}`,
232
+ receipt: o.receipt
174
233
  });
175
234
  }
176
- function D(e, i, t, r) {
177
- const c = e.artifact, o = e.scope, a = e.binding, _ = e.bindingIdentity;
178
- let u = e.receipt, s;
179
- const l = $(c, async (p) => {
180
- const d = u;
181
- if (u = void 0, d === void 0) throw new n("spend_binding_consumed");
182
- const T = Object.freeze({
183
- ...a,
184
- attemptId: J(),
185
- receipt: d
235
+ function O(e, t, i, n, o) {
236
+ const c = e.artifact, a = e.scope, d = e.binding, p = e.bindingIdentity;
237
+ let u = e.receipt, l;
238
+ const _ = t(c, async (s) => {
239
+ const q = u;
240
+ if (u = void 0, q === void 0) throw new r("spend_binding_consumed");
241
+ const R = Object.freeze({
242
+ ...d,
243
+ attemptId: Z(),
244
+ receipt: q
186
245
  });
187
246
  try {
188
- await i(T, p), s.committed = !0;
189
- } catch (E) {
190
- throw r(s), E;
247
+ await i(R, s), l.committed = !0;
248
+ } catch ($) {
249
+ throw o(l), $;
191
250
  }
192
251
  });
193
- return s = { lease: l, scope: o, bindingIdentity: _, committed: !1 }, t(s), l;
252
+ return l = { lease: _, scope: a, bindingIdentity: p, committed: !1 }, n(l), _;
194
253
  }
195
- function U(e, i) {
196
- const t = w(e, [
197
- "v",
198
- "receipt",
199
- "artifact_digest_b64u",
200
- "projection_digest_b64u",
201
- "launcher_origin",
202
- "runtime_origin",
203
- "app_origin",
204
- "consumer",
205
- "target_binding",
206
- "expires_at"
207
- ], "invalid_spend_scope");
208
- if (t.v !== 1 || typeof t.receipt != "string" || !H(t.receipt) || typeof t.artifact_digest_b64u != "string" || !B(t.artifact_digest_b64u) || typeof t.projection_digest_b64u != "string" || !B(t.projection_digest_b64u) || t.consumer !== i || typeof t.expires_at != "string" || !M(t.expires_at) || !b(t.target_binding))
209
- throw new n("invalid_spend_scope");
210
- const r = f(t.launcher_origin), c = f(t.runtime_origin), o = f(t.app_origin);
211
- if (Date.parse(t.expires_at) <= Date.now()) throw new n("expired_spend_scope");
254
+ function k(e, t) {
255
+ const i = w(
256
+ e,
257
+ [
258
+ "v",
259
+ "receipt",
260
+ "artifact_digest_b64u",
261
+ "projection_digest_b64u",
262
+ "launcher_origin",
263
+ "runtime_origin",
264
+ "app_origin",
265
+ "consumer",
266
+ "target_binding",
267
+ "expires_at"
268
+ ],
269
+ "invalid_spend_scope"
270
+ );
271
+ if (i.v !== 1 || typeof i.receipt != "string" || !H(i.receipt) || typeof i.artifact_digest_b64u != "string" || !x(i.artifact_digest_b64u) || typeof i.projection_digest_b64u != "string" || !x(i.projection_digest_b64u) || i.consumer !== t || typeof i.expires_at != "string" || !M(i.expires_at) || !b(i.target_binding))
272
+ throw new r("invalid_spend_scope");
273
+ const n = f(i.launcher_origin), o = f(i.runtime_origin), c = f(i.app_origin);
274
+ if (Date.parse(i.expires_at) <= Date.now()) throw new r("expired_spend_scope");
212
275
  return Object.freeze({
213
276
  v: 1,
214
- receipt: t.receipt,
215
- artifact_digest_b64u: t.artifact_digest_b64u,
216
- projection_digest_b64u: t.projection_digest_b64u,
217
- launcher_origin: r,
218
- runtime_origin: c,
219
- app_origin: o,
220
- consumer: i,
221
- target_binding: v(t.target_binding),
222
- expires_at: t.expires_at
277
+ receipt: i.receipt,
278
+ artifact_digest_b64u: i.artifact_digest_b64u,
279
+ projection_digest_b64u: i.projection_digest_b64u,
280
+ launcher_origin: n,
281
+ runtime_origin: o,
282
+ app_origin: c,
283
+ consumer: t,
284
+ target_binding: v(i.target_binding),
285
+ expires_at: i.expires_at
223
286
  });
224
287
  }
225
- function N(e) {
288
+ function U(e) {
226
289
  return Object.freeze({
227
290
  artifactDigestB64u: e.artifact_digest_b64u,
228
291
  projectionDigestB64u: e.projection_digest_b64u,
@@ -234,56 +297,62 @@ function N(e) {
234
297
  expiresAt: e.expires_at
235
298
  });
236
299
  }
237
- function P(e, i) {
238
- const t = w(e, [
239
- "v",
240
- "env_public_id",
241
- "floe_app",
242
- "code_space_id",
243
- "app_path",
244
- "launcher_kind",
245
- "launcher_id",
246
- "launcher_origin",
247
- "runtime_origin",
248
- "app_origin",
249
- "acquisition"
250
- ], "invalid_isolated_handoff");
251
- if (t.v !== 6 || t.env_public_id !== i.envPublicId || t.floe_app !== i.floeApp || t.code_space_id !== i.codeSpaceId || t.app_path !== i.appPath || t.launcher_kind !== i.launcherKind || t.launcher_id !== i.launcherId || t.launcher_origin !== i.launcherOrigin || t.runtime_origin !== i.runtimeOrigin || t.app_origin !== i.appOrigin)
252
- throw new n("isolated_context_mismatch");
253
- return f(t.launcher_origin), f(t.runtime_origin), f(t.app_origin), t;
300
+ function V(e, t) {
301
+ const i = w(
302
+ e,
303
+ [
304
+ "v",
305
+ "env_public_id",
306
+ "floe_app",
307
+ "code_space_id",
308
+ "app_path",
309
+ "launcher_kind",
310
+ "launcher_id",
311
+ "launcher_origin",
312
+ "runtime_origin",
313
+ "app_origin",
314
+ "acquisition"
315
+ ],
316
+ "invalid_isolated_handoff"
317
+ );
318
+ if (i.v !== 6 || i.env_public_id !== t.envPublicId || i.floe_app !== t.floeApp || i.code_space_id !== t.codeSpaceId || i.app_path !== t.appPath || i.launcher_kind !== t.launcherKind || i.launcher_id !== t.launcherId || i.launcher_origin !== t.launcherOrigin || i.runtime_origin !== t.runtimeOrigin || i.app_origin !== t.appOrigin)
319
+ throw new r("isolated_context_mismatch");
320
+ return f(i.launcher_origin), f(i.runtime_origin), f(i.app_origin), i;
254
321
  }
255
- function k(e, i, t) {
256
- if (i.consumer !== "isolated" || i.launcherOrigin !== e.launcher_origin || i.runtimeOrigin !== e.runtime_origin || i.appOrigin !== e.app_origin || e.runtime_origin !== t.runtimeOrigin || e.app_origin !== t.appOrigin)
257
- throw new n("isolated_spend_binding_mismatch");
322
+ function N(e, t, i) {
323
+ if (t.consumer !== "isolated" || t.launcherOrigin !== e.launcher_origin || t.runtimeOrigin !== e.runtime_origin || t.appOrigin !== e.app_origin || e.runtime_origin !== i.runtimeOrigin || e.app_origin !== i.appOrigin)
324
+ throw new r("isolated_spend_binding_mismatch");
258
325
  }
259
- function w(e, i, t) {
260
- if (e === null || typeof e != "object" || Array.isArray(e)) throw new n(t);
261
- const r = e, c = new Set(i), o = Object.keys(r);
262
- if (o.length !== i.length || o.some((a) => !c.has(a))) throw new n(t);
263
- return r;
326
+ function w(e, t, i) {
327
+ if (e === null || typeof e != "object" || Array.isArray(e))
328
+ throw new r(i);
329
+ const n = e, o = new Set(t), c = Object.keys(n);
330
+ if (c.length !== t.length || c.some((a) => !o.has(a)))
331
+ throw new r(i);
332
+ return n;
264
333
  }
265
334
  function f(e) {
266
- if (typeof e != "string") throw new n("invalid_spend_scope");
267
- let i;
335
+ if (typeof e != "string") throw new r("invalid_spend_scope");
336
+ let t;
268
337
  try {
269
- i = new URL(e);
338
+ t = new URL(e);
270
339
  } catch {
271
- throw new n("invalid_spend_scope");
340
+ throw new r("invalid_spend_scope");
272
341
  }
273
- if (i.protocol !== "https:" && i.protocol !== "http:" || i.origin !== e || i.username !== "" || i.password !== "")
274
- throw new n("invalid_spend_scope");
342
+ if (t.protocol !== "https:" && t.protocol !== "http:" || t.origin !== e || t.username !== "" || t.password !== "")
343
+ throw new r("invalid_spend_scope");
275
344
  return e;
276
345
  }
277
346
  function H(e) {
278
- const i = /^r1\.([A-Za-z0-9_-]{1,64})\.([A-Za-z0-9_-]+)$/u.exec(e);
279
- if (i === null || i[2] === void 0) return !1;
347
+ const t = /^r1\.([A-Za-z0-9_-]{1,64})\.([A-Za-z0-9_-]+)$/u.exec(e);
348
+ if (t === null || t[2] === void 0) return !1;
280
349
  try {
281
- return y(i[2], "invalid_spend_scope").length === j;
350
+ return y(t[2], "invalid_spend_scope").length === j;
282
351
  } catch {
283
352
  return !1;
284
353
  }
285
354
  }
286
- function B(e) {
355
+ function x(e) {
287
356
  try {
288
357
  return y(e, "invalid_spend_scope").length === j;
289
358
  } catch {
@@ -293,69 +362,78 @@ function B(e) {
293
362
  function M(e) {
294
363
  return /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z$/u.test(e) ? Number.isFinite(Date.parse(e)) : !1;
295
364
  }
296
- function b(e, i = 0) {
297
- return i > 32 ? !1 : e === null || typeof e == "string" || typeof e == "boolean" ? !0 : typeof e == "number" ? Number.isFinite(e) : Array.isArray(e) ? e.every((t) => b(t, i + 1)) : typeof e != "object" ? !1 : Object.values(e).every((t) => b(t, i + 1));
365
+ function b(e, t = 0) {
366
+ return t > 32 ? !1 : e === null || typeof e == "string" || typeof e == "boolean" ? !0 : typeof e == "number" ? Number.isFinite(e) : Array.isArray(e) ? e.every((i) => b(i, t + 1)) : typeof e != "object" ? !1 : Object.values(e).every(
367
+ (i) => b(i, t + 1)
368
+ );
298
369
  }
299
370
  function v(e) {
300
371
  if (Array.isArray(e)) {
301
- for (const i of e) v(i);
372
+ for (const t of e) v(t);
302
373
  return Object.freeze(e);
303
374
  }
304
375
  if (e !== null && typeof e == "object") {
305
- for (const i of Object.values(e)) v(i);
376
+ for (const t of Object.values(e)) v(t);
306
377
  return Object.freeze(e);
307
378
  }
308
379
  return e;
309
380
  }
310
- async function q(e, i, t) {
311
- const r = await I(e), c = y(i, t);
312
- if (r.length !== c.length) throw new n(t);
313
- let o = 0;
314
- for (let a = 0; a < r.length; a += 1) o |= r[a] ^ c[a];
315
- if (o !== 0) throw new n(t);
381
+ async function D(e, t, i) {
382
+ const n = await L(e), o = y(t, i);
383
+ if (n.length !== o.length) throw new r(i);
384
+ let c = 0;
385
+ for (let a = 0; a < n.length; a += 1)
386
+ c |= n[a] ^ o[a];
387
+ if (c !== 0) throw new r(i);
316
388
  }
317
- async function V(e) {
318
- return A(await I(e));
389
+ async function J(e) {
390
+ return B(await L(e));
319
391
  }
320
- async function I(e) {
321
- if (globalThis.crypto?.subtle === void 0) throw new n("acquisition_crypto_unavailable");
322
- const i = e.buffer.slice(e.byteOffset, e.byteOffset + e.byteLength), t = await globalThis.crypto.subtle.digest("SHA-256", i);
323
- return new Uint8Array(t);
392
+ async function L(e) {
393
+ if (globalThis.crypto?.subtle === void 0)
394
+ throw new r("acquisition_crypto_unavailable");
395
+ const t = e.buffer.slice(
396
+ e.byteOffset,
397
+ e.byteOffset + e.byteLength
398
+ ), i = await globalThis.crypto.subtle.digest("SHA-256", t);
399
+ return new Uint8Array(i);
324
400
  }
325
- function J() {
326
- if (globalThis.crypto?.getRandomValues === void 0) throw new n("acquisition_entropy_unavailable");
327
- return A(globalThis.crypto.getRandomValues(new Uint8Array(j)));
401
+ function Z() {
402
+ if (globalThis.crypto?.getRandomValues === void 0)
403
+ throw new r("acquisition_entropy_unavailable");
404
+ return B(globalThis.crypto.getRandomValues(new Uint8Array(j)));
328
405
  }
329
- function y(e, i) {
330
- if (!/^[A-Za-z0-9_-]*$/u.test(e) || e.length % 4 === 1) throw new n(i);
331
- const t = e.replace(/-/gu, "+").replace(/_/gu, "/") + "=".repeat((4 - e.length % 4) % 4);
332
- let r;
406
+ function y(e, t) {
407
+ if (!/^[A-Za-z0-9_-]*$/u.test(e) || e.length % 4 === 1) throw new r(t);
408
+ const i = e.replace(/-/gu, "+").replace(/_/gu, "/") + "=".repeat((4 - e.length % 4) % 4);
409
+ let n;
333
410
  try {
334
- r = atob(t);
411
+ n = atob(i);
335
412
  } catch {
336
- throw new n(i);
413
+ throw new r(t);
337
414
  }
338
- const c = Uint8Array.from(r, (o) => o.charCodeAt(0));
339
- if (A(c) !== e) throw new n(i);
340
- return c;
415
+ const o = Uint8Array.from(n, (c) => c.charCodeAt(0));
416
+ if (B(o) !== e) throw new r(t);
417
+ return o;
341
418
  }
342
- function A(e) {
343
- let i = "";
344
- for (const t of e) i += String.fromCharCode(t);
345
- return btoa(i).replace(/\+/gu, "-").replace(/\//gu, "_").replace(/=+$/u, "");
419
+ function B(e) {
420
+ let t = "";
421
+ for (const i of e) t += String.fromCharCode(i);
422
+ return btoa(t).replace(/\+/gu, "-").replace(/\//gu, "_").replace(/=+$/u, "");
346
423
  }
347
- function Z(e) {
424
+ function W(e) {
348
425
  return new TextEncoder().encode(e).length;
349
426
  }
350
427
  export {
351
- n as AcquisitionError,
428
+ r as AcquisitionError,
352
429
  h as ConnectedAcquisition,
353
430
  m as IsolatedOneShotAcquisition,
354
- Q as clearAcquisitionSource,
355
- ie as connectIsolatedOneShot,
356
- ee as connectedAcquisitionDetails,
357
- Y as materializeAcquisitionForSource,
358
- te as materializeIsolatedOneShot,
359
- X as registerAcquisitionSource,
360
- K as synchronizeAcquisitionSourceSnapshot
431
+ te as clearAcquisitionSource,
432
+ re as connectIsolatedOneShot,
433
+ ie as connectedAcquisitionDetails,
434
+ K as materializeAcquisitionForSource,
435
+ ne as materializeIsolatedOneShot,
436
+ Q as materializePrivateLoopbackAcquisitionForSource,
437
+ Y as registerAcquisitionSource,
438
+ ee as synchronizeAcquisitionSourceSnapshot
361
439
  };
@@ -1,4 +1,5 @@
1
1
  import type { ArtifactSource, JsonObject, RetryDisposition } from '@floegence/flowersec-core';
2
+ import type { PrivateLoopbackArtifactSourceV1 } from '@floegence/flowersec-core/browser';
2
3
  import { type CommitSpend, type ValidateSpendBinding } from './acquisition';
3
4
  export type ControlplaneArtifactSourceOptions = Readonly<{
4
5
  baseUrl: string;
@@ -14,6 +15,7 @@ export type ControlplaneArtifactSourceOptions = Readonly<{
14
15
  validateSpendBinding: ValidateSpendBinding;
15
16
  retryableBusinessCodes?: readonly string[];
16
17
  }>;
18
+ export type PrivateLoopbackControlplaneArtifactSourceOptions = Omit<ControlplaneArtifactSourceOptions, 'allowLoopbackHTTP' | 'entryTicket'>;
17
19
  export declare class ControlplaneRequestError extends Error {
18
20
  readonly status: number;
19
21
  readonly code: string;
@@ -32,3 +34,4 @@ export type ClassifiedControlplaneFailure = Readonly<{
32
34
  }>;
33
35
  export declare function classifyControlplaneFailure(input: ControlplaneFailureInput): ClassifiedControlplaneFailure;
34
36
  export declare function createControlplaneArtifactSource(options: ControlplaneArtifactSourceOptions): ArtifactSource;
37
+ export declare function createPrivateLoopbackControlplaneArtifactSource(options: PrivateLoopbackControlplaneArtifactSourceOptions): PrivateLoopbackArtifactSourceV1;
@@ -1,56 +1,71 @@
1
- import { registerAcquisitionSource as b, materializeAcquisitionForSource as h, AcquisitionError as u } from "./acquisition.js";
1
+ import { registerAcquisitionSource as b, AcquisitionError as p, materializeAcquisitionForSource as w, materializePrivateLoopbackAcquisitionForSource as k } from "./acquisition.js";
2
2
  const y = /^[a-z][a-z0-9_]{0,63}$/u;
3
- class f extends Error {
4
- constructor(t, r) {
5
- super(`Floe controlplane request failed (code=${r})`), this.status = t, this.code = r, this.name = "ControlplaneRequestError";
3
+ class a extends Error {
4
+ constructor(r, t) {
5
+ super(`Floe controlplane request failed (code=${t})`), this.status = r, this.code = t, this.name = "ControlplaneRequestError";
6
6
  }
7
7
  }
8
- function m(e) {
9
- const t = e.toLowerCase();
10
- return t === "localhost" || t === "::1" || t === "127.0.0.1" || t.startsWith("127.");
8
+ function S(e) {
9
+ const r = e.toLowerCase();
10
+ return r === "localhost" || r === "::1" || r === "127.0.0.1" || r.startsWith("127.");
11
11
  }
12
- function w(e, t) {
13
- let r;
12
+ function _(e, r) {
13
+ let t;
14
14
  try {
15
- r = new URL(e);
15
+ t = new URL(e);
16
16
  } catch {
17
- throw new f(0, "transport_policy_denied");
17
+ throw new a(0, "transport_policy_denied");
18
18
  }
19
- if (r.protocol !== "https:" && !(t && r.protocol === "http:" && m(r.hostname)))
20
- throw new f(0, "transport_policy_denied");
21
- return r.pathname = r.pathname.replace(/\/+$/u, ""), r;
19
+ if (t.protocol !== "https:" && !(r && t.protocol === "http:" && S(t.hostname)))
20
+ throw new a(0, "transport_policy_denied");
21
+ return t.pathname = t.pathname.replace(/\/+$/u, ""), t;
22
22
  }
23
- function j(e, t) {
24
- const r = t === void 0 ? "/v1/connect/artifact" : "/v1/connect/artifact/entry";
25
- return new URL(`${e.pathname}${r}`, e).toString();
23
+ function j(e, r) {
24
+ const t = r === void 0 ? "/v1/connect/artifact" : "/v1/connect/artifact/entry";
25
+ return new URL(`${e.pathname}${t}`, e).toString();
26
26
  }
27
27
  function v(e) {
28
28
  if (!y.test(e.code))
29
- return Object.freeze({ code: "invalid_error_code", disposition: Object.freeze({ kind: "terminal" }) });
29
+ return Object.freeze({
30
+ code: "invalid_error_code",
31
+ disposition: Object.freeze({ kind: "terminal" })
32
+ });
30
33
  if (new Set(e.retryableBusinessCodes ?? []).has(e.code))
31
34
  return Object.freeze({ code: e.code, disposition: Object.freeze({ kind: "retryable" }) });
32
35
  if (e.status === 429) {
33
- const r = O(e.retryAfter, e.nowUnixMilliseconds ?? Date.now());
36
+ const t = g(e.retryAfter, e.nowUnixMilliseconds ?? Date.now());
34
37
  return Object.freeze({
35
38
  code: e.code,
36
- disposition: Object.freeze(r === void 0 ? { kind: "retryable" } : { kind: "retry_after", notBeforeUnixMilliseconds: r })
39
+ disposition: Object.freeze(t === void 0 ? { kind: "retryable" } : { kind: "retry_after", notBeforeUnixMilliseconds: t })
37
40
  });
38
41
  }
39
42
  return e.status === 408 || e.status === 425 || e.status >= 500 ? Object.freeze({ code: e.code, disposition: Object.freeze({ kind: "retryable" }) }) : Object.freeze({ code: e.code, disposition: Object.freeze({ kind: "terminal" }) });
40
43
  }
41
- function _(e) {
44
+ function B(e) {
45
+ const r = m(e, w);
46
+ return b(r), r;
47
+ }
48
+ function L(e) {
49
+ const r = z(e.baseUrl), t = m(
50
+ { ...e, baseUrl: r.origin, allowLoopbackHTTP: !0 },
51
+ k
52
+ );
53
+ return b(t), t;
54
+ }
55
+ function m(e, r) {
42
56
  if (typeof e.commitSpend != "function") throw new TypeError("commitSpend is required");
43
- if (typeof e.validateSpendBinding != "function") throw new TypeError("validateSpendBinding is required");
57
+ if (typeof e.validateSpendBinding != "function")
58
+ throw new TypeError("validateSpendBinding is required");
44
59
  const t = e.fetch ?? globalThis.fetch;
45
60
  if (typeof t != "function") throw new TypeError("fetch is required");
46
- const r = w(e.baseUrl, e.allowLoopbackHTTP === !0), n = j(r, e.entryTicket), c = {
47
- acquire: async ({ signal: i }) => {
61
+ const n = _(e.baseUrl, e.allowLoopbackHTTP === !0), s = j(n, e.entryTicket), i = {
62
+ acquire: async ({ signal: d }) => {
48
63
  try {
49
64
  const o = {
50
65
  endpoint_id: e.endpointId,
51
66
  ...e.payload === void 0 ? {} : { payload: e.payload },
52
67
  ...e.entryTicket === void 0 && e.correlation !== void 0 ? { correlation: { trace_id: e.correlation.traceId } } : {}
53
- }, a = await t(n, {
68
+ }, c = await t(s, {
54
69
  method: "POST",
55
70
  headers: {
56
71
  accept: "application/json",
@@ -60,39 +75,39 @@ function _(e) {
60
75
  body: JSON.stringify(o),
61
76
  credentials: "omit",
62
77
  redirect: "error",
63
- signal: i
78
+ signal: d
64
79
  });
65
- if (!a.ok) {
66
- const s = await z(a);
80
+ if (!c.ok) {
81
+ const l = await E(c);
67
82
  return { kind: "failure", ...v({
68
- status: a.status,
69
- code: s,
70
- retryAfter: a.headers.get("retry-after"),
83
+ status: c.status,
84
+ code: l,
85
+ retryAfter: c.headers.get("retry-after"),
71
86
  retryableBusinessCodes: e.retryableBusinessCodes
72
87
  }) };
73
88
  }
74
- let l;
89
+ let u;
75
90
  try {
76
- l = await a.json();
91
+ u = await c.json();
77
92
  } catch {
78
- return d("invalid_controlplane_response");
93
+ return f("invalid_controlplane_response");
79
94
  }
80
- const p = await h(c, l, {
95
+ const h = await r(i, u, {
81
96
  commitSpend: e.commitSpend,
82
- validateSpendBinding: (s) => {
97
+ validateSpendBinding: (l) => {
83
98
  try {
84
- return e.validateSpendBinding(s);
99
+ return e.validateSpendBinding(l);
85
100
  } catch {
86
- throw new u("invalid_spend_binding");
101
+ throw new p("invalid_spend_binding");
87
102
  }
88
103
  },
89
104
  expectedConsumer: "trusted"
90
105
  });
91
- return Object.freeze({ kind: "lease", lease: p });
106
+ return Object.freeze({ kind: "lease", lease: h });
92
107
  } catch (o) {
93
- if (i.aborted) throw i.reason ?? new DOMException("Aborted", "AbortError");
108
+ if (d.aborted) throw d.reason ?? new DOMException("Aborted", "AbortError");
94
109
  if (o instanceof DOMException && o.name === "AbortError") throw o;
95
- return o instanceof u || o instanceof f ? d(o.code) : Object.freeze({
110
+ return o instanceof p || o instanceof a ? f(o.code) : Object.freeze({
96
111
  kind: "failure",
97
112
  code: "network_error",
98
113
  disposition: Object.freeze({ kind: "retryable" })
@@ -100,15 +115,34 @@ function _(e) {
100
115
  }
101
116
  }
102
117
  };
103
- return b(c), c;
118
+ return i;
119
+ }
120
+ function z(e) {
121
+ let r;
122
+ try {
123
+ r = new URL(e);
124
+ } catch {
125
+ throw new a(0, "transport_policy_denied");
126
+ }
127
+ if (e !== r.origin || r.protocol !== "http:" || r.username !== "" || r.password !== "" || !O(r.port) || !A(r.hostname))
128
+ throw new a(0, "transport_policy_denied");
129
+ return r;
130
+ }
131
+ function O(e) {
132
+ if (!/^[1-9][0-9]*$/u.test(e)) return !1;
133
+ const r = Number(e);
134
+ return Number.isSafeInteger(r) && r >= 1024 && r <= 65535;
135
+ }
136
+ function A(e) {
137
+ return e === "127.0.0.1" || e === "[::1]";
104
138
  }
105
- async function z(e) {
139
+ async function E(e) {
106
140
  try {
107
- const t = await e.json();
108
- if (t !== null && typeof t == "object" && !Array.isArray(t)) {
109
- const r = t.error;
110
- if (r !== null && typeof r == "object" && !Array.isArray(r)) {
111
- const n = r.code;
141
+ const r = await e.json();
142
+ if (r !== null && typeof r == "object" && !Array.isArray(r)) {
143
+ const t = r.error;
144
+ if (t !== null && typeof t == "object" && !Array.isArray(t)) {
145
+ const n = t.code;
112
146
  if (typeof n == "string") return n;
113
147
  }
114
148
  }
@@ -116,19 +150,19 @@ async function z(e) {
116
150
  }
117
151
  return "request_failed";
118
152
  }
119
- function O(e, t) {
153
+ function g(e, r) {
120
154
  if (e == null) return;
121
- const r = e.trim();
122
- if (/^\d+$/u.test(r)) {
123
- const c = Number(r);
124
- if (!Number.isSafeInteger(c)) return;
125
- const i = t + c * 1e3;
126
- return Number.isSafeInteger(i) && i > t ? i : void 0;
155
+ const t = e.trim();
156
+ if (/^\d+$/u.test(t)) {
157
+ const s = Number(t);
158
+ if (!Number.isSafeInteger(s)) return;
159
+ const i = r + s * 1e3;
160
+ return Number.isSafeInteger(i) && i > r ? i : void 0;
127
161
  }
128
- const n = Date.parse(r);
129
- return Number.isSafeInteger(n) && n > t ? n : void 0;
162
+ const n = Date.parse(t);
163
+ return Number.isSafeInteger(n) && n > r ? n : void 0;
130
164
  }
131
- function d(e) {
165
+ function f(e) {
132
166
  return Object.freeze({
133
167
  kind: "failure",
134
168
  code: y.test(e) ? e : "invalid_error_code",
@@ -136,7 +170,8 @@ function d(e) {
136
170
  });
137
171
  }
138
172
  export {
139
- f as ControlplaneRequestError,
173
+ a as ControlplaneRequestError,
140
174
  v as classifyControlplaneFailure,
141
- _ as createControlplaneArtifactSource
175
+ B as createControlplaneArtifactSource,
176
+ L as createPrivateLoopbackControlplaneArtifactSource
142
177
  };
@@ -1,13 +1,20 @@
1
1
  import type { ArtifactSource } from '@floegence/flowersec-core';
2
- import type { ConnectionControllerOptions } from '@floegence/flowersec-core/browser';
2
+ import type { ConnectionControllerOptions, PrivateLoopbackArtifactSourceV1, PrivateLoopbackConnectionControllerOptionsV1 } from '@floegence/flowersec-core/browser';
3
3
  import { type AcquisitionConnectionLifecycle } from './acquisition-lifecycle';
4
4
  import type { ConnectedAcquisition } from './acquisition';
5
5
  import type { ProxyBootstrapOwner } from './proxy-bootstrap';
6
- export type FlowersecConnectionConfig = Readonly<{
7
- source: ArtifactSource;
8
- controller?: ConnectionControllerOptions;
6
+ type SharedFlowersecConnectionConfig = Readonly<{
9
7
  lifecycle: AcquisitionConnectionLifecycle;
10
8
  }>;
9
+ export type FlowersecConnectionConfig = SharedFlowersecConnectionConfig & (Readonly<{
10
+ source: ArtifactSource;
11
+ controller?: ConnectionControllerOptions;
12
+ privateLoopback?: never;
13
+ }> | Readonly<{
14
+ source: PrivateLoopbackArtifactSourceV1;
15
+ privateLoopback: PrivateLoopbackConnectionControllerOptionsV1;
16
+ controller?: never;
17
+ }>);
11
18
  type AcquisitionConnectionOptions = Readonly<{
12
19
  source: ArtifactSource;
13
20
  controller?: ConnectionControllerOptions;
@@ -15,10 +22,16 @@ type AcquisitionConnectionOptions = Readonly<{
15
22
  }>;
16
23
  export type TunnelArtifactConnectionOptions = AcquisitionConnectionOptions;
17
24
  export type DirectArtifactConnectionOptions = AcquisitionConnectionOptions;
25
+ export type PrivateLoopbackDirectConnectionOptions = Readonly<{
26
+ source: PrivateLoopbackArtifactSourceV1;
27
+ privateLoopback: PrivateLoopbackConnectionControllerOptionsV1;
28
+ onConnected?: (acquisition: ConnectedAcquisition) => void;
29
+ }>;
18
30
  export type ProxyRuntimeTunnelConnectionOptions = AcquisitionConnectionOptions & Readonly<{
19
31
  proxyBootstrap: ProxyBootstrapOwner;
20
32
  }>;
21
33
  export declare function createArtifactTunnelConnectionConfig(options: TunnelArtifactConnectionOptions): FlowersecConnectionConfig;
22
34
  export declare function createProxyRuntimeTunnelConnectionConfig(options: ProxyRuntimeTunnelConnectionOptions): FlowersecConnectionConfig;
23
35
  export declare function createArtifactDirectConnectionConfig(options: DirectArtifactConnectionOptions): FlowersecConnectionConfig;
36
+ export declare function createPrivateLoopbackDirectConnectionConfig(options: PrivateLoopbackDirectConnectionOptions): FlowersecConnectionConfig;
24
37
  export {};
@@ -1,5 +1,5 @@
1
1
  import { createAcquisitionConnectionLifecycle as r } from "./acquisition-lifecycle.js";
2
- function o(e) {
2
+ function t(e) {
3
3
  return n(e);
4
4
  }
5
5
  function i(e) {
@@ -8,6 +8,15 @@ function i(e) {
8
8
  function u(e) {
9
9
  return n(e);
10
10
  }
11
+ function f(e) {
12
+ return Object.freeze({
13
+ source: e.source,
14
+ privateLoopback: e.privateLoopback,
15
+ lifecycle: r(e.source, {
16
+ ...e.onConnected === void 0 ? {} : { onConnected: e.onConnected }
17
+ })
18
+ });
19
+ }
11
20
  function n(e, c) {
12
21
  return Object.freeze({
13
22
  source: e.source,
@@ -20,6 +29,7 @@ function n(e, c) {
20
29
  }
21
30
  export {
22
31
  u as createArtifactDirectConnectionConfig,
23
- o as createArtifactTunnelConnectionConfig,
32
+ t as createArtifactTunnelConnectionConfig,
33
+ f as createPrivateLoopbackDirectConnectionConfig,
24
34
  i as createProxyRuntimeTunnelConnectionConfig
25
35
  };
package/dist/index.d.ts CHANGED
@@ -1,19 +1,19 @@
1
- export { clearLocationHash, parseHashParam, } from './hash';
1
+ export { clearLocationHash, parseHashParam } from './hash';
2
2
  export type { WaitForMessageOptions } from './messaging';
3
3
  export { postMessageToOrigins, waitForMessage } from './messaging';
4
4
  export { getSessionStorage, removeSessionStorage, setSessionStorage } from './storage';
5
5
  export type { ArtifactSource, ArtifactSourceResult } from '@floegence/flowersec-core';
6
- export { createControlplaneArtifactSource, ControlplaneRequestError } from './artifact-source';
6
+ export { createControlplaneArtifactSource, createPrivateLoopbackControlplaneArtifactSource, ControlplaneRequestError, } from './artifact-source';
7
7
  export { classifyControlplaneFailure } from './artifact-source';
8
- export type { ClassifiedControlplaneFailure, ControlplaneArtifactSourceOptions, ControlplaneFailureInput, } from './artifact-source';
9
- export { AcquisitionError, clearAcquisitionSource, connectIsolatedOneShot, ConnectedAcquisition, IsolatedOneShotAcquisition, materializeIsolatedOneShot, synchronizeAcquisitionSourceSnapshot, } from './acquisition';
8
+ export type { ClassifiedControlplaneFailure, ControlplaneArtifactSourceOptions, ControlplaneFailureInput, PrivateLoopbackControlplaneArtifactSourceOptions, } from './artifact-source';
9
+ export { AcquisitionError, clearAcquisitionSource, connectIsolatedOneShot, ConnectedAcquisition, IsolatedOneShotAcquisition, materializePrivateLoopbackAcquisitionForSource, materializeIsolatedOneShot, synchronizeAcquisitionSourceSnapshot, } from './acquisition';
10
10
  export type { CommitSpend, CriticalScopeProjectionV1, IsolatedHandoffValidationContext, MaterializeIsolatedOneShotOptions, RuntimeBootInitPayloadV6, SerializedAcquisitionEnvelopeV1, SpendBindingView, SpendCommitRequest, SpendScopeV1, ValidateSpendBinding, } from './acquisition';
11
11
  export { createAcquisitionConnectionLifecycle } from './acquisition-lifecycle';
12
12
  export type { AcquisitionConnectionLifecycle, AcquisitionConnectionLifecycleOptions, } from './acquisition-lifecycle';
13
- export type { DirectArtifactConnectionOptions, FlowersecConnectionConfig, ProxyRuntimeTunnelConnectionOptions, TunnelArtifactConnectionOptions, } from './connection';
14
- export { createArtifactDirectConnectionConfig, createArtifactTunnelConnectionConfig, createProxyRuntimeTunnelConnectionConfig, } from './connection';
13
+ export type { DirectArtifactConnectionOptions, FlowersecConnectionConfig, PrivateLoopbackDirectConnectionOptions, ProxyRuntimeTunnelConnectionOptions, TunnelArtifactConnectionOptions, } from './connection';
14
+ export { createArtifactDirectConnectionConfig, createArtifactTunnelConnectionConfig, createPrivateLoopbackDirectConnectionConfig, createProxyRuntimeTunnelConnectionConfig, } from './connection';
15
15
  export type { FetchServerSentEventsOptions, ServerSentEvent, ServerSentEventStreamErrorCode, } from './server-sent-events';
16
- export { fetchServerSentEvents, ServerSentEventStreamError, } from './server-sent-events';
16
+ export { fetchServerSentEvents, ServerSentEventStreamError } from './server-sent-events';
17
17
  export { closeProxyBootstrap, createProxyBootstrapOwner, ProxyBootstrapOwner, synchronizeProxyBootstrap, } from './proxy-bootstrap';
18
18
  export type { ControllerBridgeProxyBootstrapContext, ProxyBootstrapBinding, ProxyBootstrapOwnerOptions, ProxyBootstrapSnapshot, ServiceWorkerProxyBootstrapContext, } from './proxy-bootstrap';
19
19
  export type { ScopeEnvelope, ScopeResolver, ScopeResolverMap, ValidatedCriticalScopeProjection, } from './scope';
package/dist/index.js CHANGED
@@ -1,43 +1,46 @@
1
1
  import { clearLocationHash as r, parseHashParam as t } from "./hash.js";
2
2
  import { postMessageToOrigins as i, waitForMessage as a } from "./messaging.js";
3
- import { getSessionStorage as c, removeSessionStorage as S, setSessionStorage as p } from "./storage.js";
4
- import { ControlplaneRequestError as f, classifyControlplaneFailure as m, createControlplaneArtifactSource as x } from "./artifact-source.js";
5
- import { AcquisitionError as C, ConnectedAcquisition as E, IsolatedOneShotAcquisition as O, clearAcquisitionSource as y, connectIsolatedOneShot as A, materializeIsolatedOneShot as P, synchronizeAcquisitionSourceSnapshot as g } from "./acquisition.js";
6
- import { createAcquisitionConnectionLifecycle as h } from "./acquisition-lifecycle.js";
7
- import { createArtifactDirectConnectionConfig as v, createArtifactTunnelConnectionConfig as B, createProxyRuntimeTunnelConnectionConfig as T } from "./connection.js";
8
- import { ServerSentEventStreamError as d, fetchServerSentEvents as I } from "./server-sent-events.js";
9
- import { ProxyBootstrapOwner as M, closeProxyBootstrap as w, createProxyBootstrapOwner as z, synchronizeProxyBootstrap as F } from "./proxy-bootstrap.js";
10
- import { FLOWERSEC_BOOTSTRAP_SCOPE_RESOLVERS as N, PROXY_RUNTIME_SCOPE_NAME as D, createBootstrapScopeResolvers as U, validateProxyRuntimeScopeEntry as V } from "./scope.js";
3
+ import { getSessionStorage as s, removeSessionStorage as S, setSessionStorage as p } from "./storage.js";
4
+ import { ControlplaneRequestError as f, classifyControlplaneFailure as u, createControlplaneArtifactSource as m, createPrivateLoopbackControlplaneArtifactSource as C } from "./artifact-source.js";
5
+ import { AcquisitionError as E, ConnectedAcquisition as P, IsolatedOneShotAcquisition as A, clearAcquisitionSource as O, connectIsolatedOneShot as g, materializeIsolatedOneShot as y, materializePrivateLoopbackAcquisitionForSource as v, synchronizeAcquisitionSourceSnapshot as R } from "./acquisition.js";
6
+ import { createAcquisitionConnectionLifecycle as q } from "./acquisition-lifecycle.js";
7
+ import { createArtifactDirectConnectionConfig as B, createArtifactTunnelConnectionConfig as T, createPrivateLoopbackDirectConnectionConfig as _, createProxyRuntimeTunnelConnectionConfig as d } from "./connection.js";
8
+ import { ServerSentEventStreamError as F, fetchServerSentEvents as I } from "./server-sent-events.js";
9
+ import { ProxyBootstrapOwner as b, closeProxyBootstrap as k, createProxyBootstrapOwner as w, synchronizeProxyBootstrap as D } from "./proxy-bootstrap.js";
10
+ import { FLOWERSEC_BOOTSTRAP_SCOPE_RESOLVERS as N, PROXY_RUNTIME_SCOPE_NAME as U, createBootstrapScopeResolvers as V, validateProxyRuntimeScopeEntry as W } from "./scope.js";
11
11
  export {
12
- C as AcquisitionError,
13
- E as ConnectedAcquisition,
12
+ E as AcquisitionError,
13
+ P as ConnectedAcquisition,
14
14
  f as ControlplaneRequestError,
15
15
  N as FLOWERSEC_BOOTSTRAP_SCOPE_RESOLVERS,
16
- O as IsolatedOneShotAcquisition,
17
- D as PROXY_RUNTIME_SCOPE_NAME,
18
- M as ProxyBootstrapOwner,
19
- d as ServerSentEventStreamError,
20
- m as classifyControlplaneFailure,
21
- y as clearAcquisitionSource,
16
+ A as IsolatedOneShotAcquisition,
17
+ U as PROXY_RUNTIME_SCOPE_NAME,
18
+ b as ProxyBootstrapOwner,
19
+ F as ServerSentEventStreamError,
20
+ u as classifyControlplaneFailure,
21
+ O as clearAcquisitionSource,
22
22
  r as clearLocationHash,
23
- w as closeProxyBootstrap,
24
- A as connectIsolatedOneShot,
25
- h as createAcquisitionConnectionLifecycle,
26
- v as createArtifactDirectConnectionConfig,
27
- B as createArtifactTunnelConnectionConfig,
28
- U as createBootstrapScopeResolvers,
29
- x as createControlplaneArtifactSource,
30
- z as createProxyBootstrapOwner,
31
- T as createProxyRuntimeTunnelConnectionConfig,
23
+ k as closeProxyBootstrap,
24
+ g as connectIsolatedOneShot,
25
+ q as createAcquisitionConnectionLifecycle,
26
+ B as createArtifactDirectConnectionConfig,
27
+ T as createArtifactTunnelConnectionConfig,
28
+ V as createBootstrapScopeResolvers,
29
+ m as createControlplaneArtifactSource,
30
+ C as createPrivateLoopbackControlplaneArtifactSource,
31
+ _ as createPrivateLoopbackDirectConnectionConfig,
32
+ w as createProxyBootstrapOwner,
33
+ d as createProxyRuntimeTunnelConnectionConfig,
32
34
  I as fetchServerSentEvents,
33
- c as getSessionStorage,
34
- P as materializeIsolatedOneShot,
35
+ s as getSessionStorage,
36
+ y as materializeIsolatedOneShot,
37
+ v as materializePrivateLoopbackAcquisitionForSource,
35
38
  t as parseHashParam,
36
39
  i as postMessageToOrigins,
37
40
  S as removeSessionStorage,
38
41
  p as setSessionStorage,
39
- g as synchronizeAcquisitionSourceSnapshot,
40
- F as synchronizeProxyBootstrap,
41
- V as validateProxyRuntimeScopeEntry,
42
+ R as synchronizeAcquisitionSourceSnapshot,
43
+ D as synchronizeProxyBootstrap,
44
+ W as validateProxyRuntimeScopeEntry,
42
45
  a as waitForMessage
43
46
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@floegence/floe-webapp-boot",
3
- "version": "0.44.1",
3
+ "version": "0.45.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -35,7 +35,7 @@
35
35
  "clean": "rm -rf dist *.tsbuildinfo"
36
36
  },
37
37
  "dependencies": {
38
- "@floegence/flowersec-core": "3.1.1"
38
+ "@floegence/flowersec-core": "3.2.0"
39
39
  },
40
40
  "devDependencies": {
41
41
  "typescript": "^5.9.3",