@effect-agent/platform-cloudflare 0.1.0-beta.117 → 0.1.0-beta.119
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CloudflareThreadClient.d.mts +50 -50
- package/dist/ProtectedBrowser.d.mts +6 -1
- package/dist/ProtectedBrowser.mjs +58 -19
- package/dist/ProtectedBrowser.mjs.map +1 -1
- package/dist/{ThreadObject-S05rNeF7.d.mts → ThreadObject-D_prWu8-.d.mts} +30 -30
- package/dist/ThreadObject.d.mts +1 -1
- package/dist/index.d.mts +1 -1
- package/package.json +1 -1
- package/src/protected-browser/host.ts +4 -1
- package/src/protected-browser/inspect-frame.ts +21 -7
- package/src/protected-browser/native.ts +14 -2
- package/src/protected-browser/policy.ts +18 -3
|
@@ -1540,50 +1540,13 @@ export declare const encodeHostResponse: (input: AbortRecorded | ApprovalRecorde
|
|
|
1540
1540
|
} | {
|
|
1541
1541
|
readonly _tag: "HostFailed";
|
|
1542
1542
|
readonly failure: {
|
|
1543
|
-
readonly _tag: "
|
|
1544
|
-
readonly
|
|
1545
|
-
} | {
|
|
1546
|
-
readonly _tag: "AgentInputError";
|
|
1547
|
-
readonly message: string;
|
|
1548
|
-
} | {
|
|
1549
|
-
readonly _tag: "DigestError";
|
|
1543
|
+
readonly _tag: "DurableAlarmError";
|
|
1544
|
+
readonly operation: string;
|
|
1550
1545
|
readonly message: string;
|
|
1551
1546
|
readonly cause?: Schema.Json | undefined;
|
|
1552
1547
|
} | {
|
|
1553
|
-
readonly _tag: "
|
|
1548
|
+
readonly _tag: "ThreadNotMaterialized";
|
|
1554
1549
|
readonly threadId: string;
|
|
1555
|
-
readonly principal: string;
|
|
1556
|
-
readonly idempotencyKey: string;
|
|
1557
|
-
readonly existingInputDigest: string;
|
|
1558
|
-
readonly attemptedInputDigest: string;
|
|
1559
|
-
} | {
|
|
1560
|
-
readonly _tag: "AdmissionPolicyError";
|
|
1561
|
-
readonly reason: "occupied" | "refused" | "unavailable";
|
|
1562
|
-
readonly code: string;
|
|
1563
|
-
readonly cause?: import("effect-agent/failure-diagnostic").Diagnostic | undefined;
|
|
1564
|
-
readonly stack?: string | undefined;
|
|
1565
|
-
} | {
|
|
1566
|
-
readonly _tag: "SettlementConflict";
|
|
1567
|
-
readonly submissionId: string;
|
|
1568
|
-
readonly existingOutcome: "aborted" | "completed" | "failed";
|
|
1569
|
-
} | {
|
|
1570
|
-
readonly _tag: "ApprovalConflict";
|
|
1571
|
-
readonly submissionId: string;
|
|
1572
|
-
readonly toolCallId: string;
|
|
1573
|
-
readonly existingDecision: "approved" | "denied";
|
|
1574
|
-
} | {
|
|
1575
|
-
readonly _tag: "UnknownResolutionConflict";
|
|
1576
|
-
readonly submissionId: string;
|
|
1577
|
-
readonly toolCallId: string;
|
|
1578
|
-
} | {
|
|
1579
|
-
readonly _tag: "JoinedToHost";
|
|
1580
|
-
readonly submissionId: string;
|
|
1581
|
-
readonly hostSubmissionId: string;
|
|
1582
|
-
} | {
|
|
1583
|
-
readonly _tag: "LedgerError";
|
|
1584
|
-
readonly operation: string;
|
|
1585
|
-
readonly message: string;
|
|
1586
|
-
readonly cause?: import("effect-agent/failure-diagnostic").Diagnostic | undefined;
|
|
1587
1550
|
} | {
|
|
1588
1551
|
readonly _tag: "ThreadStoreError";
|
|
1589
1552
|
readonly operation: string;
|
|
@@ -1597,8 +1560,10 @@ export declare const encodeHostResponse: (input: AbortRecorded | ApprovalRecorde
|
|
|
1597
1560
|
readonly sequence?: number | undefined;
|
|
1598
1561
|
} | undefined;
|
|
1599
1562
|
} | {
|
|
1600
|
-
readonly _tag: "
|
|
1601
|
-
readonly
|
|
1563
|
+
readonly _tag: "LedgerError";
|
|
1564
|
+
readonly operation: string;
|
|
1565
|
+
readonly message: string;
|
|
1566
|
+
readonly cause?: import("effect-agent/failure-diagnostic").Diagnostic | undefined;
|
|
1602
1567
|
} | {
|
|
1603
1568
|
readonly _tag: "AppendConflict";
|
|
1604
1569
|
readonly threadId: string;
|
|
@@ -1611,25 +1576,60 @@ export declare const encodeHostResponse: (input: AbortRecorded | ApprovalRecorde
|
|
|
1611
1576
|
readonly threadId: string;
|
|
1612
1577
|
readonly actualEpoch: number;
|
|
1613
1578
|
readonly attemptedEpoch: number;
|
|
1579
|
+
} | {
|
|
1580
|
+
readonly _tag: "OperationDenied";
|
|
1581
|
+
readonly operation: "abort" | "awaitSettlement" | "explain" | "observe" | "resolveApproval" | "resolveUnknown" | "retry" | "scanObligations" | "verify" | "wake";
|
|
1582
|
+
readonly reason: string;
|
|
1583
|
+
readonly threadId?: string | undefined;
|
|
1584
|
+
readonly submissionId?: string | undefined;
|
|
1585
|
+
} | {
|
|
1586
|
+
readonly _tag: "AdmissionConflict";
|
|
1587
|
+
readonly threadId: string;
|
|
1588
|
+
readonly principal: string;
|
|
1589
|
+
readonly idempotencyKey: string;
|
|
1590
|
+
readonly existingInputDigest: string;
|
|
1591
|
+
readonly attemptedInputDigest: string;
|
|
1592
|
+
} | {
|
|
1593
|
+
readonly _tag: "AdmissionPolicyError";
|
|
1594
|
+
readonly reason: "occupied" | "refused" | "unavailable";
|
|
1595
|
+
readonly code: string;
|
|
1596
|
+
readonly cause?: import("effect-agent/failure-diagnostic").Diagnostic | undefined;
|
|
1597
|
+
readonly stack?: string | undefined;
|
|
1598
|
+
} | {
|
|
1599
|
+
readonly _tag: "AgentInputError";
|
|
1600
|
+
readonly message: string;
|
|
1601
|
+
} | {
|
|
1602
|
+
readonly _tag: "DigestError";
|
|
1603
|
+
readonly message: string;
|
|
1604
|
+
readonly cause?: Schema.Json | undefined;
|
|
1614
1605
|
} | {
|
|
1615
1606
|
readonly _tag: "DurableRuntimeFailpointError";
|
|
1616
1607
|
readonly location: "abort:after-intent" | "approval:after-request-append" | "approval:after-suspend" | "checkpoint:after-save" | "checkpoint:before-save" | "claim:after-claim" | "compaction:after-canonical-append" | "compaction:before-canonical-append" | "input:after-canonical-append" | "join:after-canonical-append" | "join:after-claim" | "policy:after-reservation-append" | "policy:before-reservation-append" | "resolve:after-intent" | "run:after-duration-append" | "run:after-start-append" | "run:before-duration-append" | "run:before-start-append" | "step:after-step-append" | "subagent:after-admit" | "subagent:after-child-abort-intent" | "subagent:after-child-ready" | "subagent:after-join-append" | "subagent:after-release" | "subagent:after-release-pending" | "subagent:after-request-append" | "subagent:after-reserve" | "subagent:after-sibling-settle" | "subagent:after-start-append" | "subagent:after-suspend" | "subagent:before-join-append" | "submit:after-admit" | "submit:after-materialize" | "terminalize:after-canonical-append" | "terminalize:after-reserve" | "tools:after-prepared-append" | "tools:after-unavailable-append" | "tools:before-prepared-append" | "tools:before-unavailable-append" | "turn:after-canonical-append" | "turn:after-response-append" | "turn:after-results-append" | "update:after-canonical-append" | "update:after-delivery-insert" | "update:before-canonical-append" | "update:before-delivery-insert" | "worker:after-completion-append" | "worker:after-origin-append" | "worker:after-report-append" | "worker:after-report-delivery" | "worker:after-source-append" | "worker:after-stop-append" | "worker:after-stop-seal" | "worker:after-subtree-append" | "worker:before-completion-append" | "worker:before-origin-append" | "worker:before-report-append" | "worker:before-report-delivery" | "worker:before-source-append" | "worker:before-stop-append" | "worker:before-stop-seal" | "worker:before-subtree-append";
|
|
1608
|
+
} | {
|
|
1609
|
+
readonly _tag: "SettlementConflict";
|
|
1610
|
+
readonly submissionId: string;
|
|
1611
|
+
readonly existingOutcome: "aborted" | "completed" | "failed";
|
|
1612
|
+
} | {
|
|
1613
|
+
readonly _tag: "JoinedToHost";
|
|
1614
|
+
readonly submissionId: string;
|
|
1615
|
+
readonly hostSubmissionId: string;
|
|
1617
1616
|
} | {
|
|
1618
1617
|
readonly _tag: "AdmissionLimitExceeded";
|
|
1619
1618
|
readonly limit: "database-bytes" | "input-bytes" | "queue-depth";
|
|
1620
1619
|
readonly actual: number;
|
|
1621
1620
|
readonly maximum: number;
|
|
1622
1621
|
} | {
|
|
1623
|
-
readonly _tag: "
|
|
1624
|
-
readonly operation: string;
|
|
1622
|
+
readonly _tag: "HostProtocolError";
|
|
1625
1623
|
readonly message: string;
|
|
1626
|
-
readonly cause?: Schema.Json | undefined;
|
|
1627
1624
|
} | {
|
|
1628
|
-
readonly _tag: "
|
|
1629
|
-
readonly
|
|
1630
|
-
readonly
|
|
1631
|
-
readonly
|
|
1632
|
-
|
|
1625
|
+
readonly _tag: "ApprovalConflict";
|
|
1626
|
+
readonly submissionId: string;
|
|
1627
|
+
readonly toolCallId: string;
|
|
1628
|
+
readonly existingDecision: "approved" | "denied";
|
|
1629
|
+
} | {
|
|
1630
|
+
readonly _tag: "UnknownResolutionConflict";
|
|
1631
|
+
readonly submissionId: string;
|
|
1632
|
+
readonly toolCallId: string;
|
|
1633
1633
|
};
|
|
1634
1634
|
}, Schema.SchemaError, never>;
|
|
1635
1635
|
export declare const decodeHostResponse: (input: unknown, options?: import("effect/SchemaAST").ParseOptions) => Effect.Effect<AbortRecorded | ApprovalRecorded | HostFailed | ObservedPage | ProgressCancelled | ProgressObserved | SettlementReached | SubmissionStatusResponse | SubmitSucceeded | UnknownResolutionRecorded, Schema.SchemaError, never>;
|
|
@@ -9,6 +9,8 @@ declare const ProtectedTransportError_base: Schema.Class<ProtectedTransportError
|
|
|
9
9
|
declare class ProtectedTransportError extends ProtectedTransportError_base {}
|
|
10
10
|
declare const ProtectedBrowserDispatch_base: Context.ServiceClass<ProtectedBrowserDispatch, "@effect-agent/platform-cloudflare/ProtectedBrowserDispatch", {
|
|
11
11
|
readonly mark: Effect.Effect<void>;
|
|
12
|
+
/** Only an acknowledged reply before assignment may restore the preceding dispatch evidence. */
|
|
13
|
+
readonly confirmNoWrite: Effect.Effect<void>;
|
|
12
14
|
}>;
|
|
13
15
|
/** Per-write evidence authority, provided by the policy immediately around a transport fill. */
|
|
14
16
|
declare class ProtectedBrowserDispatch extends ProtectedBrowserDispatch_base {}
|
|
@@ -96,7 +98,10 @@ interface BrowserRunProtectedSession {
|
|
|
96
98
|
readonly getHandoffState: Effect.Effect<BrowserRunHandoffState, ProtectedBrowserError>;
|
|
97
99
|
/** Read only the exact page’s current origin after its recorded handoff completes; tools remain paused. */
|
|
98
100
|
readonly getReturnOrigin: Effect.Effect<typeof CredentialOrigin.Type, ProtectedBrowserError>;
|
|
99
|
-
/**
|
|
101
|
+
/**
|
|
102
|
+
* Resume a committed pause; human handoffs also require provider completion. Returns no page data.
|
|
103
|
+
* A fresh authorized observation must succeed before page actions or credential operations.
|
|
104
|
+
*/
|
|
100
105
|
readonly returnControl: Effect.Effect<void, ProtectedBrowserError>;
|
|
101
106
|
/** Release this attachment only after committing its suspended checkpoint; preserve the remote browser. */
|
|
102
107
|
readonly detach: Effect.Effect<void, ProtectedBrowserError>;
|
|
@@ -173,7 +173,7 @@ const makeProtectedBrowserPolicy = Effect.fn("ProtectedBrowser.open")(function*
|
|
|
173
173
|
const error = cause.reasons.find((reason) => reason._tag === "Fail" && Schema.is(ProtectedBrowserError)(reason.error));
|
|
174
174
|
const reason = unexpected.length === 0 && error?._tag === "Fail" && Schema.is(ProtectedBrowserError)(error.error) ? error.error.reason : "provider";
|
|
175
175
|
const interrupt = cause.reasons.some((reason) => reason._tag === "Interrupt");
|
|
176
|
-
if (dispatch
|
|
176
|
+
if (dispatch === "possibly-dispatched" || dispatch === "dispatched" && reason !== "busy" || interrupt || reason === "provider" || reason === "timeout") yield* close;
|
|
177
177
|
if (interrupt) return yield* Effect.interrupt;
|
|
178
178
|
const outcome = fail(dispatch === "possibly-dispatched" && reason === "provider" ? "outcome-unknown" : reason);
|
|
179
179
|
return yield* unexpected.length > 0 ? reportedBrowserError(outcome) : inheritBrowserReport(error?._tag === "Fail" ? error.error : void 0, outcome);
|
|
@@ -267,9 +267,15 @@ const makeProtectedBrowserPolicy = Effect.fn("ProtectedBrowser.open")(function*
|
|
|
267
267
|
target: control.target,
|
|
268
268
|
role: control.role
|
|
269
269
|
});
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
270
|
+
const previousDispatch = dispatch;
|
|
271
|
+
yield* publicFailure(driver.fill(decoded.ref, control.role, Redacted.make(decoded.value))).pipe(Effect.provideService(ProtectedBrowserDispatch, {
|
|
272
|
+
mark: Effect.sync(() => {
|
|
273
|
+
dispatch = "possibly-dispatched";
|
|
274
|
+
}),
|
|
275
|
+
confirmNoWrite: Effect.sync(() => {
|
|
276
|
+
dispatch = previousDispatch;
|
|
277
|
+
})
|
|
278
|
+
}));
|
|
273
279
|
dispatch = "dispatched";
|
|
274
280
|
milestone = "filled";
|
|
275
281
|
yield* permitObservation;
|
|
@@ -356,11 +362,17 @@ const makeProtectedBrowserPolicy = Effect.fn("ProtectedBrowser.open")(function*
|
|
|
356
362
|
yield* authorize;
|
|
357
363
|
const value = secretFor(material, field.role);
|
|
358
364
|
if (value === void 0) return yield* fail("missing-credential");
|
|
365
|
+
const previousDispatch = dispatch;
|
|
359
366
|
observation = "protected";
|
|
360
|
-
yield* publicFailure(driver.fill(field.ref, field.role, value)).pipe(Effect.provideService(ProtectedBrowserDispatch, {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
367
|
+
yield* publicFailure(driver.fill(field.ref, field.role, value)).pipe(Effect.provideService(ProtectedBrowserDispatch, {
|
|
368
|
+
mark: Effect.sync(() => {
|
|
369
|
+
dispatch = "possibly-dispatched";
|
|
370
|
+
if (!exposures.some((target) => sameTarget(target, offer.target))) exposures.push(offer.target);
|
|
371
|
+
}),
|
|
372
|
+
confirmNoWrite: Effect.sync(() => {
|
|
373
|
+
dispatch = previousDispatch;
|
|
374
|
+
})
|
|
375
|
+
}));
|
|
364
376
|
dispatch = "dispatched";
|
|
365
377
|
milestone = "partial-fill";
|
|
366
378
|
}
|
|
@@ -422,7 +434,6 @@ const makeProtectedBrowserPolicy = Effect.fn("ProtectedBrowser.open")(function*
|
|
|
422
434
|
returnControl: locked(Effect.gen(function* () {
|
|
423
435
|
if (detached || observation === "closed") return yield* fail("closed");
|
|
424
436
|
if (!suspended) return yield* fail("denied");
|
|
425
|
-
yield* permitObservation;
|
|
426
437
|
offers.clear();
|
|
427
438
|
driver.resetReferences();
|
|
428
439
|
needsObservation = true;
|
|
@@ -505,12 +516,26 @@ const inspectFrame = `(() => {
|
|
|
505
516
|
} else if (el instanceof HTMLButtonElement || (el instanceof HTMLInputElement && ['submit','button'].includes(type))) {
|
|
506
517
|
if (!el.matches(':disabled')) role = type === 'submit' && form ? 'submit' : type === 'button' ? 'button' : 'unsupported';
|
|
507
518
|
} else if (el instanceof HTMLAnchorElement) role = 'link';
|
|
519
|
+
const options = [];
|
|
520
|
+
let truncated = false;
|
|
521
|
+
if (role === 'select') {
|
|
522
|
+
for (let index = 0; index < el.options.length; index++) {
|
|
523
|
+
if (index === 256) { truncated = true; break; }
|
|
524
|
+
const option = el.options[index];
|
|
525
|
+
const label = option.label.trim();
|
|
526
|
+
// Never publish a shortened label as an exact fill choice.
|
|
527
|
+
if (label.length > 200) { truncated = true; continue; }
|
|
528
|
+
options.push({label, selected: option.selected, disabled: option.matches(':disabled')});
|
|
529
|
+
}
|
|
530
|
+
}
|
|
508
531
|
const fingerprint = JSON.stringify([role, action, method, enctype, name, completion, type, choiceValue]);
|
|
509
532
|
return { role, formIndex, action, fingerprint, ...(isChoice(el) ? {checked: el.checked} : {}),
|
|
533
|
+
...(role === 'select' ? {options, truncated} : {}),
|
|
510
534
|
label: (labelText(el) ?? (nativeField ? '' : el.textContent) ?? '').slice(0,200) };
|
|
511
535
|
};
|
|
512
|
-
const expose = ({role, formIndex, action, label, checked}) =>
|
|
513
|
-
({role, formIndex, action, label, ...(checked === undefined ? {} : {checked})
|
|
536
|
+
const expose = ({role, formIndex, action, label, checked, options, truncated}) =>
|
|
537
|
+
({role, formIndex, action, label, ...(checked === undefined ? {} : {checked}),
|
|
538
|
+
...(options === undefined ? {} : {options, truncated})});
|
|
514
539
|
const original = elements.map(describe);
|
|
515
540
|
const validate = (index) => {
|
|
516
541
|
const current = describe(elements[index]);
|
|
@@ -540,13 +565,13 @@ const inspectFrame = `(() => {
|
|
|
540
565
|
const current = validate(index);
|
|
541
566
|
if (!current || current.role !== role) return false;
|
|
542
567
|
const el = elements[index];
|
|
543
|
-
if (
|
|
568
|
+
if (el instanceof HTMLSelectElement) {
|
|
544
569
|
const options = [...el.options].filter(option => !option.matches(':disabled'));
|
|
545
|
-
|
|
546
|
-
const matches =
|
|
547
|
-
if (matches.length !== 1) return 'unsupported';
|
|
570
|
+
// Ordinary fills name the visible choice; credential material stays a private value.
|
|
571
|
+
const matches = options.filter(option => (role === 'select' ? option.label.trim() : option.value) === value);
|
|
572
|
+
if (matches.length !== 1) return 'unsupported-before-write';
|
|
548
573
|
value = matches[0].value;
|
|
549
|
-
if ([...el.options].filter(option => option.value === value).length !== 1) return 'unsupported';
|
|
574
|
+
if ([...el.options].filter(option => option.value === value).length !== 1) return 'unsupported-before-write';
|
|
550
575
|
}
|
|
551
576
|
let prototype = Object.getPrototypeOf(el);
|
|
552
577
|
let setter;
|
|
@@ -576,9 +601,17 @@ const Description = Schema.Struct({
|
|
|
576
601
|
formIndex: Schema.Natural,
|
|
577
602
|
action: Schema.String.check(Schema.isMaxLength(maxAttributeLength)),
|
|
578
603
|
label: Schema.String.check(Schema.isMaxLength(200)),
|
|
579
|
-
checked: Schema.optionalKey(Schema.Boolean)
|
|
604
|
+
checked: Schema.optionalKey(Schema.Boolean),
|
|
605
|
+
options: ProtectedBrowserControl.fields.options,
|
|
606
|
+
truncated: Schema.optionalKey(Schema.Boolean)
|
|
580
607
|
});
|
|
581
608
|
const Descriptions = Schema.Array(Schema.NullOr(Description)).check(Schema.isMaxLength(65));
|
|
609
|
+
const FillResult = Schema.Literals([
|
|
610
|
+
true,
|
|
611
|
+
false,
|
|
612
|
+
"unsupported-before-write",
|
|
613
|
+
"unsupported"
|
|
614
|
+
]);
|
|
582
615
|
/** One host-private acquired session. The SDK handles and exact-session cleanup have one owner. */
|
|
583
616
|
var ProtectedNativeSession = class extends Context.Service()("@effect-agent/platform-cloudflare/ProtectedNativeSession") {};
|
|
584
617
|
const transportError = (reason) => new ProtectedTransportError({ reason });
|
|
@@ -749,6 +782,7 @@ const makeProtectedNativeTransport = Effect.fn("ProtectedNativeTransport.make")(
|
|
|
749
782
|
for (let index = 0; index < descriptions.length; index++) {
|
|
750
783
|
const desc = descriptions[index];
|
|
751
784
|
if (!desc) continue;
|
|
785
|
+
if (desc.truncated) truncated = true;
|
|
752
786
|
if (discovered.length === 64) {
|
|
753
787
|
truncated = true;
|
|
754
788
|
break;
|
|
@@ -765,6 +799,7 @@ const makeProtectedNativeTransport = Effect.fn("ProtectedNativeTransport.make")(
|
|
|
765
799
|
role: desc.role,
|
|
766
800
|
label: desc.label,
|
|
767
801
|
...desc.checked === void 0 ? {} : { checked: desc.checked },
|
|
802
|
+
...desc.options === void 0 ? {} : { options: desc.options },
|
|
768
803
|
...desc.role === "link" ? { url: desc.action } : {},
|
|
769
804
|
target: CredentialTarget.make({
|
|
770
805
|
topOrigin: before.topOrigin,
|
|
@@ -806,7 +841,7 @@ const makeProtectedNativeTransport = Effect.fn("ProtectedNativeTransport.make")(
|
|
|
806
841
|
const dispatch = yield* ProtectedBrowserDispatch;
|
|
807
842
|
const state = yield* get(ref);
|
|
808
843
|
yield* dispatch.mark;
|
|
809
|
-
const
|
|
844
|
+
const raw = yield* remote("protected.fill", () => state.frame.handle.evaluate((held, index, expectedRole, secret) => {
|
|
810
845
|
if (typeof held !== "object" || held === null) return false;
|
|
811
846
|
return Reflect.apply(Reflect.get(held, "fill"), held, [
|
|
812
847
|
index,
|
|
@@ -814,8 +849,12 @@ const makeProtectedNativeTransport = Effect.fn("ProtectedNativeTransport.make")(
|
|
|
814
849
|
secret
|
|
815
850
|
]);
|
|
816
851
|
}, state.index, role, Redacted.value(value)));
|
|
852
|
+
const filled = yield* decode(FillResult, raw);
|
|
853
|
+
if (filled === false || filled === "unsupported-before-write") {
|
|
854
|
+
yield* dispatch.confirmNoWrite;
|
|
855
|
+
return yield* transportError(filled === false ? "stale-reference" : "unsupported");
|
|
856
|
+
}
|
|
817
857
|
if (filled === "unsupported") return yield* transportError("unsupported");
|
|
818
|
-
if (filled !== true) return yield* transportError("stale-reference");
|
|
819
858
|
}),
|
|
820
859
|
click: Effect.fn("ProtectedNativeTransport.click")(function* (ref) {
|
|
821
860
|
const state = yield* get(ref);
|