@fkn/lib 0.9.33 → 0.9.35

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 (96) hide show
  1. package/account.cjs +1 -1
  2. package/account.d.ts +6 -6
  3. package/account.js +3 -3
  4. package/{api-Cc5qxCHP.d.ts → api-CfmRAze5.d.ts} +3 -1
  5. package/{api-BlAtp6lc.js → api-CtiKFcK3.js} +62 -47
  6. package/api-Djf-XdZ4.cjs +3 -0
  7. package/api.cjs +1 -1
  8. package/api.d.ts +2 -2
  9. package/api.js +1 -1
  10. package/attach-policy.cjs +1 -1
  11. package/attach-policy.d.ts +32 -7
  12. package/attach-policy.js +16 -18
  13. package/cloud/dns.d.ts +1 -1
  14. package/cloud/fetch.cjs +1 -1
  15. package/cloud/fetch.d.ts +1 -1
  16. package/cloud/fetch.js +1 -1
  17. package/cloud/fs/promises.d.ts +3 -4
  18. package/cloud/fs.cjs +1 -1
  19. package/cloud/fs.d.ts +2 -2
  20. package/cloud/fs.js +2 -2
  21. package/cloud/net.d.ts +1 -1
  22. package/cloud-B9Sd7V1g.js +422 -0
  23. package/cloud-DCWD_0sd.cjs +1 -0
  24. package/{cloud-D0Ebu5bX.d.ts → cloud-DxitkM7z.d.ts} +9 -5
  25. package/cloud.cjs +1 -1
  26. package/cloud.d.ts +4 -4
  27. package/cloud.js +2 -2
  28. package/{contract-CahPObYc.d.ts → contract-D37GGkou.d.ts} +146 -1
  29. package/contract.cjs +1 -0
  30. package/contract.d.ts +2 -2
  31. package/contract.js +28 -0
  32. package/desktop.d.ts +7 -7
  33. package/dgram.cjs +1 -1
  34. package/dgram.d.ts +5 -5
  35. package/dgram.js +1 -1
  36. package/dns.cjs +1 -1
  37. package/dns.d.ts +3 -3
  38. package/dns.js +1 -1
  39. package/extension-DJQ0oYdk.js +89 -0
  40. package/extension-DSrUjoLw.cjs +1 -0
  41. package/{extension-DNkuFy1Y.d.ts → extension-TRYu_aG-.d.ts} +36 -157
  42. package/extension.cjs +1 -1
  43. package/extension.d.ts +3 -3
  44. package/extension.js +3 -3
  45. package/fs/promises.cjs +1 -1
  46. package/fs/promises.d.ts +3 -3
  47. package/fs/promises.js +1 -1
  48. package/{fs-CYcErwc4.d.ts → fs--NhtUyYa.d.ts} +1 -1
  49. package/{fs-BSsWw8HM.js → fs-BvNZePtN.js} +4 -4
  50. package/{fs-DxDxbvRS.cjs → fs-D8RCGFNc.cjs} +1 -1
  51. package/fs.cjs +1 -1
  52. package/fs.d.ts +2 -2
  53. package/fs.js +1 -1
  54. package/hosts-C4-8lWwz.js +161 -0
  55. package/hosts-DD4rDeQH.cjs +1 -0
  56. package/http.d.ts +20 -20
  57. package/{index-DH3_12nU.d.ts → index-C_Lqta5o.d.ts} +385 -7
  58. package/{index-Cg6y_FTi.d.ts → index-kuPqkS_-.d.ts} +26 -3
  59. package/index.cjs +1 -1
  60. package/index.d.ts +25 -10
  61. package/index.js +68 -62
  62. package/{lib-duLPF_WZ.js → lib-B-jGWfsv.js} +597 -396
  63. package/lib-Cjd91q7g.cjs +53 -0
  64. package/{net-BXPEJToS.d.ts → net-0SlODFSM.d.ts} +2 -2
  65. package/net.cjs +1 -1
  66. package/net.d.ts +1 -1
  67. package/net.js +1 -1
  68. package/node-fs-BNTPsX5c.cjs +1 -0
  69. package/{node-fs-C9ECR_9H.js → node-fs-BZy9bzKd.js} +2 -2
  70. package/opfs/promises.d.ts +2 -2
  71. package/opfs.cjs +1 -1
  72. package/opfs.d.ts +2 -2
  73. package/opfs.js +1 -1
  74. package/package.json +1 -1
  75. package/packages.cjs +1 -1
  76. package/packages.d.ts +27 -27
  77. package/packages.js +1 -1
  78. package/{proxy-DxiJU5Y_.d.ts → proxy-Bmb2wxG1.d.ts} +2 -2
  79. package/proxy-CYcaW5ew.cjs +1 -0
  80. package/proxy-DDwY3AVG.js +60 -0
  81. package/react.d.ts +3 -3
  82. package/rooms.cjs +1 -1
  83. package/rooms.d.ts +8 -8
  84. package/rooms.js +1 -1
  85. package/{storage-Bo01npo9.js → storage-BbcnDCnc.js} +1 -1
  86. package/{storage-WZEvw3KN.d.ts → storage-ZrY4Y4L5.d.ts} +21 -2
  87. package/{storage-DEjjVCT2.cjs → storage-dSi2dUKx.cjs} +1 -1
  88. package/api-Beky02FK.cjs +0 -3
  89. package/cloud-BZmduWyX.cjs +0 -1
  90. package/cloud-DaVb11IV.js +0 -174
  91. package/extension-D70dtUvW.cjs +0 -1
  92. package/extension-DdXNlt9_.js +0 -84
  93. package/lib-DLM2M3_i.cjs +0 -53
  94. package/node-fs-DZPGCYWg.cjs +0 -1
  95. package/proxy-DexG-Wmk.cjs +0 -1
  96. package/proxy-VY0HRl2E.js +0 -75
@@ -38,6 +38,15 @@ type OperationModule = {
38
38
  * refused by name instead of quietly doing something else.
39
39
  */
40
40
  kind?: ChainKind;
41
+ /**
42
+ * The argument list a gate sees when `ensure(operation, options)` asks about this operation.
43
+ *
44
+ * Without it the gate gets `[options]`, which is right for an operation whose options are its first
45
+ * argument. An operation that takes them later must say where, or a gate keyed on an argument
46
+ * settles a different key at `ensure` than the real call does: `fetch(url, init)` reads the method
47
+ * from `args[1]`, so it declares `options => [undefined, options]`.
48
+ */
49
+ ensureArgs?: (options: Record<string, unknown>) => unknown[];
41
50
  };
42
51
  type KindModules = {
43
52
  selectors: Record<string, SelectorModule>;
@@ -61,7 +70,16 @@ type GateTools = {
61
70
  };
62
71
  type Gate = (request: OperationRequest, tools: GateTools) => void | Promise<void>;
63
72
  type Executor = {
64
- execute: (parts: SelectorPart[], operation: string, args: unknown[]) => Promise<unknown>;
73
+ /**
74
+ * Runs `operation` on what `parts` resolve to, in whichever realm the chain lands in.
75
+ *
76
+ * `context` is an opaque per-call value for the host: frame-locator never reads it, and carries it
77
+ * unchanged through every pivot and across the window bridge, so each executor the call passes
78
+ * through hands it to its own `assertRealm` (see `ExecutorOptions`). It crosses a window by structured
79
+ * clone, so it must be cloneable. A chain built with `createFrameLocator` never sends one; only a
80
+ * caller holding the executor itself can.
81
+ */
82
+ execute: (parts: SelectorPart[], operation: string, args: unknown[], context?: unknown) => Promise<unknown>;
65
83
  highlight: (parts: SelectorPart[], on: boolean) => Promise<void>;
66
84
  stale?: Promise<void>;
67
85
  };
@@ -112,14 +130,39 @@ type FrameFetchResult = {
112
130
  headers: [string, string][];
113
131
  body: ArrayBuffer;
114
132
  };
115
- //#endregion
116
- //#region ../frame-locator/lib/operations.d.ts
133
+ declare namespace operations_d_exports {
134
+ export { PositionOptions$1 as PositionOptions, click, count, exists, fill, getAttribute, hover, isVisible, textContent };
135
+ }
117
136
  type PositionOptions$1 = OperationOptions & {
118
137
  position?: {
119
138
  x?: number;
120
139
  y?: number;
121
140
  };
122
141
  };
142
+ declare const click: {
143
+ readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void;
144
+ };
145
+ declare const hover: {
146
+ readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void;
147
+ };
148
+ declare const fill: {
149
+ readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void;
150
+ };
151
+ declare const textContent: {
152
+ readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string;
153
+ };
154
+ declare const getAttribute: {
155
+ readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null;
156
+ };
157
+ declare const isVisible: {
158
+ readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean;
159
+ };
160
+ declare const count: {
161
+ readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number;
162
+ };
163
+ declare const exists: {
164
+ readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean;
165
+ };
123
166
  //#endregion
124
167
  //#region ../frame-locator/lib/modules.d.ts
125
168
  declare const defaultModules: {
@@ -244,6 +287,7 @@ declare const defaultModules: {
244
287
  };
245
288
  readonly fetch: {
246
289
  readonly kind: ChainKind;
290
+ readonly ensureArgs: (options: Record<string, unknown>) => unknown[];
247
291
  readonly resolve: (context: LocatorContext, url: string, init?: FrameFetchInit) => Promise<FrameFetchResult>;
248
292
  };
249
293
  };
@@ -283,6 +327,11 @@ type ToOf<M> = M extends {
283
327
  to: infer K extends ChainKind;
284
328
  } ? K : 'element';
285
329
  type ChainOf<M extends Modules, K extends ChainKind> = K extends 'frame' ? FrameLocator<M> : Locator$1<M>;
330
+ /**
331
+ * What `ensure` may carry. An option no gate reads is accepted and ignored rather than refused:
332
+ * `subtree` is the one apps still pass, and the scope it once narrowed is now decided per site by
333
+ * the gate, so passing it changes nothing.
334
+ */
286
335
  type EnsureOptions = OperationOptions & Record<string, unknown>;
287
336
  type Chain<M extends Modules, K extends ChainKind> = { [N in keyof M[K]['selectors']]: (...args: ArgsOf<M[K]['selectors'][N]>) => ChainOf<M, ToOf<M[K]['selectors'][N]>>; } & { [N in keyof M[K]['operations']]: (...args: ArgsOf<M[K]['operations'][N]>) => Promise<ResultOf<M[K]['operations'][N]>>; } & {
288
337
  ensure: (operation: Extract<keyof M[K]['operations'], string>, options?: EnsureOptions) => Promise<void>;
@@ -530,6 +579,7 @@ declare const locatorModules: Extended<{
530
579
  };
531
580
  readonly fetch: {
532
581
  readonly kind: ChainKind;
582
+ readonly ensureArgs: (options: Record<string, unknown>) => unknown[];
533
583
  readonly resolve: (context: LocatorContext, url: string, init?: FrameFetchInit) => Promise<FrameFetchResult>;
534
584
  };
535
585
  };
@@ -574,24 +624,260 @@ declare const locatorModules: Extended<{
574
624
  fetch: {
575
625
  resolve: (context: LocatorContext, url: string, init?: FrameFetchOptions) => Promise<FrameFetchResult>;
576
626
  kind: ChainKind;
627
+ ensureArgs: (options: Record<string, unknown>) => unknown[];
577
628
  };
578
629
  };
579
630
  };
580
631
  }>;
581
632
  type LocatorModules = typeof locatorModules;
582
633
  //#endregion
634
+ //#region ../web-extension/lib/permission/shared/permission.d.ts
635
+ /**
636
+ * The four categories a grant is asked and stored under. Every descriptor names one, so a key
637
+ * without a category does not compile. Category ids carry no dot and registry keys always do, so the
638
+ * two can share the grant key column without colliding.
639
+ */
640
+ type PermissionCategory = 'interaction' | 'storage' | 'network' | 'evaluation';
641
+ /**
642
+ * What a category row says. `heading` is the name the popup, dashboard and activity log print;
643
+ * `summary` is the owner's one-line account of the category. The row copy is a template over
644
+ * `site`, the host the row consults (or its "first and N more" form), with a cloud variant for the
645
+ * card, where no render proxy jar holds the user's browser cookies.
646
+ */
647
+ type CategoryMeta = {
648
+ id: PermissionCategory;
649
+ heading: string;
650
+ summary: string;
651
+ title: (site: string) => string;
652
+ /** `signedIn` is false when the frame was attached with `syncCookies: false` */
653
+ description: (site: string, signedIn: boolean) => string;
654
+ cloudTitle: (site: string) => string;
655
+ cloudDescription: (site: string) => string;
656
+ };
657
+ /** The four categories, in display order. The word Storage never appears: it already means FKN account storage. */
658
+ declare const CATEGORIES: readonly CategoryMeta[];
659
+ //#endregion
660
+ //#region ../web-extension/lib/permission/shared/registry.d.ts
661
+ /** Every shipped descriptor. The derived values below read the ACTIVE registry, which is this list unless a test swapped it. */
662
+ declare const PERMISSIONS: readonly [{
663
+ readonly scope: 'read.text';
664
+ readonly category: 'storage';
665
+ readonly severity: 1;
666
+ readonly chip: 'read text';
667
+ readonly title: 'Read text from the page';
668
+ readonly description: 'Lets the app see the text shown on this page.';
669
+ }, {
670
+ readonly scope: 'read.info';
671
+ readonly category: 'storage';
672
+ readonly severity: 1;
673
+ readonly chip: 'read details';
674
+ readonly title: 'Read info from the page';
675
+ readonly description: 'Lets the app read a detail of a part of the page.';
676
+ }, {
677
+ readonly scope: 'read.visible';
678
+ readonly category: 'storage';
679
+ readonly severity: 0;
680
+ readonly title: 'See what’s visible on the page';
681
+ readonly description: 'Lets the app check which elements are currently on screen.';
682
+ }, {
683
+ readonly scope: 'read.check';
684
+ readonly category: 'storage';
685
+ readonly severity: 0;
686
+ readonly title: 'Check if something is on the page';
687
+ readonly description: 'Lets the app test whether a specific element exists.';
688
+ }, {
689
+ readonly scope: 'read.count';
690
+ readonly category: 'storage';
691
+ readonly severity: 0;
692
+ readonly title: 'Count items on the page';
693
+ readonly description: 'Lets the app count how many matching elements are present.';
694
+ }, {
695
+ readonly scope: 'act.click';
696
+ readonly category: 'interaction';
697
+ readonly severity: 3;
698
+ readonly chip: 'click';
699
+ readonly title: 'Click on the page';
700
+ readonly description: 'Lets the app press buttons or links for you.';
701
+ }, {
702
+ readonly scope: 'act.type';
703
+ readonly category: 'interaction';
704
+ readonly severity: 1;
705
+ readonly chip: 'type';
706
+ readonly title: 'Type into a text field';
707
+ readonly description: 'Lets the app fill in form fields on your behalf.';
708
+ }, {
709
+ readonly scope: 'act.hover';
710
+ readonly category: 'interaction';
711
+ readonly severity: 1;
712
+ readonly chip: 'hover';
713
+ readonly title: 'Hover over the page';
714
+ readonly description: 'Lets the app point at things to reveal menus or tooltips.';
715
+ }, {
716
+ readonly scope: 'media.video';
717
+ readonly category: 'interaction';
718
+ readonly severity: 0;
719
+ readonly title: 'Control video playback';
720
+ readonly description: 'Lets the app play, pause, seek, and read the video on the page.';
721
+ }, {
722
+ readonly scope: 'media.appear';
723
+ readonly category: 'interaction';
724
+ readonly severity: 0;
725
+ readonly title: 'Change page appearance';
726
+ readonly description: 'Lets the app restyle parts of the page (safely filtered).';
727
+ }, {
728
+ readonly scope: 'media.appearU';
729
+ readonly category: 'evaluation';
730
+ readonly severity: 2;
731
+ readonly chip: 'unfiltered styles';
732
+ readonly unsafe: true;
733
+ readonly title: 'Change page appearance (unsafe)';
734
+ readonly description: 'Lets the app restyle the page WITHOUT safety filtering. Could be used to leak data over the network.';
735
+ }, {
736
+ readonly scope: 'embed.iframe';
737
+ readonly category: 'interaction';
738
+ readonly severity: 0;
739
+ readonly title: 'Load another website inside this app';
740
+ readonly description: 'Lets the app embed external pages directly inside its own view.';
741
+ }, {
742
+ readonly scope: 'embed.open';
743
+ readonly category: 'interaction';
744
+ readonly severity: 0;
745
+ readonly title: 'Open a website inside this app';
746
+ readonly description: 'Lets the app navigate to another site without leaving its window.';
747
+ }, {
748
+ readonly scope: 'frame.fetchRead';
749
+ readonly category: 'network';
750
+ readonly severity: 3;
751
+ readonly chip: 'load';
752
+ readonly unsafe: true;
753
+ readonly title: 'Read your account data on this site';
754
+ readonly description: 'Lets the app read pages and data from this site as you, using the session in the frame.';
755
+ }, {
756
+ readonly scope: 'frame.fetchWrite';
757
+ readonly category: 'network';
758
+ readonly severity: 3;
759
+ readonly chip: 'send';
760
+ readonly unsafe: true;
761
+ readonly title: 'Change your account data on this site';
762
+ readonly description: 'Lets the app send changes to this site as you, using the session in the frame.';
763
+ }, {
764
+ readonly scope: 'network.fetch';
765
+ readonly category: 'network';
766
+ readonly severity: 0;
767
+ readonly title: 'Fetch data from other sites';
768
+ readonly description: 'Lets the app download public data from other websites directly, past the usual cross-origin limits.';
769
+ }, {
770
+ readonly scope: 'network.fetchCredentialed';
771
+ readonly category: 'network';
772
+ readonly severity: 3;
773
+ readonly chip: 'load as you';
774
+ readonly unsafe: true;
775
+ readonly title: 'Fetch from other sites, signed in as you';
776
+ readonly description: 'Lets the app fetch other sites using your logged-in session cookies, so it can read data only you should see.';
777
+ }, {
778
+ readonly scope: 'network.fetchLocal';
779
+ readonly category: 'network';
780
+ readonly severity: 3;
781
+ readonly chip: 'local network';
782
+ readonly unsafe: true;
783
+ readonly title: 'Access devices on your local network';
784
+ readonly description: 'Lets the app reach devices and services on your home or work network, which websites normally cannot touch.';
785
+ }, {
786
+ readonly scope: 'network.readCookie';
787
+ readonly category: 'network';
788
+ readonly severity: 3;
789
+ readonly chip: 'read cookie';
790
+ readonly unsafe: true;
791
+ readonly title: 'Read a site’s cookie';
792
+ readonly description: 'Lets the app read a named cookie from another site, which can include the login token only that site should see.';
793
+ }, {
794
+ readonly scope: 'network.modifyRequestHeaders';
795
+ readonly category: 'network';
796
+ readonly severity: 2;
797
+ readonly chip: 'rewrite headers';
798
+ readonly unsafe: true;
799
+ readonly title: 'Rewrite request headers to other sites';
800
+ readonly description: 'Lets the app set or remove headers (like Origin and Referer) on this page’s own requests to the listed sites.';
801
+ }];
802
+ type PermissionScope = (typeof PERMISSIONS)[number]['scope'];
803
+ //#endregion
804
+ //#region ../web-extension/lib/permission/shared/category-request.d.ts
805
+ /** What one ask was answered. `key` is set only where the ask named a critical key, which is granted on its own row. */
806
+ type CategoryAnswer = {
807
+ category: PermissionCategory;
808
+ key?: PermissionScope;
809
+ hosts: string[];
810
+ allow: boolean;
811
+ };
812
+ //#endregion
813
+ //#region ../web-extension/lib/lib/permissions.d.ts
814
+ /**
815
+ * One whole category, asked for at once. The category is the unit the user grants, so accepting it
816
+ * covers every capability in it on the hosts the ask names.
817
+ *
818
+ * `key` is an alias for its grant key: a critical key asks for its own row, any other key asks for
819
+ * the category it belongs to.
820
+ */
821
+ type CategoryRequest = {
822
+ category: PermissionCategory;
823
+ reason?: string;
824
+ } | {
825
+ key: PermissionScope;
826
+ reason?: string;
827
+ };
828
+ /** What one category ask was answered. `key` is present only when the row asked was a critical key's own. */
829
+ type CategoryGrant = CategoryAnswer;
830
+ /**
831
+ * @deprecated the pre-category item. Accepted on any extension version and forwarded unchanged, so
832
+ * an app built against an older `@fkn/lib` keeps today's behaviour. Prefer the category form.
833
+ */
834
+ type LegacyPermissionRequest = {
835
+ key: PermissionScope;
836
+ scope?: string;
837
+ reason?: string;
838
+ };
839
+ /** `hosts` is what makes an item a category ask; without it the item is the legacy per-key one. */
840
+ type PermissionRequest = (CategoryRequest & {
841
+ hosts: string[];
842
+ }) | LegacyPermissionRequest;
843
+ /**
844
+ * `key` and `scope` are set only for a legacy answer, `category` and `hosts` only for a category one.
845
+ * A legacy answer also carries `site`, the host its scope named, empty where the scope names none
846
+ * (a locator selector), which is the case that is always refused.
847
+ */
848
+ type PermissionGrant = CategoryGrant | {
849
+ key: PermissionScope;
850
+ scope: string;
851
+ site: string;
852
+ allow: boolean;
853
+ };
854
+ declare const permissions: {
855
+ /**
856
+ * Asks for permissions on one sheet (extension) or card (cloud), in the order given, and answers
857
+ * one grant per request.
858
+ *
859
+ * A category ask needs `hosts`, the sites the grant applies to, and is answered `allow: true` only
860
+ * where every one of them was granted. It needs an extension that serves categories and throws
861
+ * `ExtensionOutdatedError` below that; a legacy `{ key, scope }` item is forwarded to any version.
862
+ *
863
+ * An ask naming a category or key the registry cannot place on a row is a `TypeError`, thrown
864
+ * before anything is sent: its answer would have to name a category the caller never asked for.
865
+ */
866
+ request: (requests: PermissionRequest[]) => Promise<PermissionGrant[]>;
867
+ };
868
+ //#endregion
583
869
  //#region ../web-extension/lib/lib/frame-core.d.ts
584
870
  type Locator = Locator$1<LocatorModules>;
585
871
  declare const attachFramePermission: {
586
872
  readonly scope: 'embed.iframe';
587
- readonly category: 'embed';
873
+ readonly category: 'interaction';
588
874
  readonly severity: 0;
589
875
  readonly title: 'Load another website inside this app';
590
876
  readonly description: 'Lets the app embed external pages directly inside its own view.';
591
877
  };
592
878
  declare const gotoPermission: {
593
879
  readonly scope: 'embed.open';
594
- readonly category: 'embed';
880
+ readonly category: 'interaction';
595
881
  readonly severity: 0;
596
882
  readonly title: 'Open a website inside this app';
597
883
  readonly description: 'Lets the app navigate to another site without leaving its window.';
@@ -603,23 +889,115 @@ type GotoOptions = {
603
889
  type Frame = FrameLocator<LocatorModules> & {
604
890
  goto(url: string, options?: GotoOptions): Promise<void>;
605
891
  url(): string;
892
+ /**
893
+ * Asks for whole categories on this attachment's hosts, before any call. Resolves per request, in
894
+ * the order they were asked; a refusal is `allow: false`, never a rejection. An ask naming a
895
+ * category or key the registry cannot place on a row is a `TypeError`, thrown before it is sent.
896
+ */
897
+ request(requests: CategoryRequest[]): Promise<CategoryGrant[]>;
606
898
  };
607
899
  type AttachFrameOptions = {
608
900
  iframe: HTMLIFrameElement;
609
901
  domains?: string[];
610
902
  syncCookies?: boolean;
611
903
  lockdown?: boolean;
904
+ /**
905
+ * Whole categories to ask for on one sheet or card right after the attach, before it resolves. A
906
+ * refusal does not reject the attach: it surfaces on the first refused operation.
907
+ */
908
+ permissions?: CategoryRequest[];
909
+ };
910
+ /** Where an attachment's window opens and how big it asks to be. */
911
+ type FrameWindowOptions = {
912
+ /**
913
+ * Where the window opens: an http or https address, which must also pass the rules an iframe src
914
+ * does. Omitted, the window opens blank and the app navigates it with `goto`, which is how an app
915
+ * keeps the click's activation when the url needs an await first.
916
+ */
917
+ url?: string;
918
+ /** Inner width in CSS pixels, 500 by default. The browser may clamp it. */
919
+ width?: number;
920
+ /** Inner height in CSS pixels, 700 by default. The browser may clamp it. */
921
+ height?: number;
922
+ };
923
+ /**
924
+ * `attachFrame`'s options when the attachment is a new window rather than an iframe.
925
+ *
926
+ * Call `attachFrame` directly in the click or key handler: the window opens before the first await,
927
+ * with the activation of that event, and the browser's popup rules apply to it as to any page's own
928
+ * `window.open`. `iframe` and `lockdown` do not apply to a window, and passing either is a TypeError.
929
+ */
930
+ type AttachWindowOptions = {
931
+ window: FrameWindowOptions;
932
+ domains?: string[];
933
+ /**
934
+ * Cloud, true by default: the window uses the cookie jar of the app that opened it, the same jar
935
+ * as that app's inline frames. A window whose app is on another site shares cookies only with
936
+ * those frames; its site storage stays its own. False: a jar of the window's own that ends with
937
+ * it. Extension: false is a TypeError, since the window is the site's own first-party tab.
938
+ */
939
+ syncCookies?: boolean;
940
+ /** Whole categories asked for once the window has connected, drawn in the window on the cloud backend. */
941
+ permissions?: CategoryRequest[];
612
942
  };
943
+ /** The Frame of an attachment that lives in its own window. */
944
+ type WindowFrame = Frame & {
945
+ /**
946
+ * Ends the attachment and closes the window. On the cloud backend it first waits, at most 2
947
+ * seconds, for the window's cookie changes to be committed to its jar, so a `goto` on the app's
948
+ * inline frame right after sees the session. Idempotent, and never rejects.
949
+ */
950
+ close(): Promise<void>;
951
+ /**
952
+ * Resolves once the attachment has ended: the window was closed by anyone, reloaded, or left the
953
+ * page FKN attached; it stopped answering (a crash, a frozen page); it lost the app's cookie jar
954
+ * mid-session; or the app page went away. Never rejects. Calls made after it resolved reject with
955
+ * the terminal detach error.
956
+ */
957
+ closed: Promise<void>;
958
+ };
959
+ /**
960
+ * `window.open` returned null, so nothing was opened: the call ran without user activation, the
961
+ * popup blocker refused it, or the calling frame is sandboxed without `allow-popups`.
962
+ */
963
+ declare class FrameWindowBlockedError extends Error {
964
+ readonly name = "FrameWindowBlockedError";
965
+ constructor();
966
+ }
967
+ /**
968
+ * Why a window refused to attach.
969
+ * `'jar-unreachable'`: the cookie jar of the app that opened it could not be reached.
970
+ * `'bad-url'`: the window would not open that address.
971
+ * `'opaque-opener'`: this page's origin is opaque (a sandboxed frame without `allow-same-origin`,
972
+ * or a `file:` page). A window can never address such a page, so none is opened.
973
+ * `'unknown'`: a reason this library does not know, sent by a newer window.
974
+ */
975
+ type FrameWindowRefusal = 'jar-unreachable' | 'bad-url' | 'opaque-opener' | 'unknown';
976
+ /** The window refused to attach, by `reason`, after loading nothing. */
977
+ declare class FrameWindowRefusedError extends Error {
978
+ readonly name = "FrameWindowRefusedError";
979
+ readonly reason: FrameWindowRefusal;
980
+ /** `reason` is what the window said; anything this library does not know becomes `'unknown'`. */
981
+ constructor(reason: unknown);
982
+ }
613
983
  type FrameBackend = {
614
984
  executor: Executor;
615
985
  gate?: Gate;
616
986
  goto(url: string, options?: GotoOptions): Promise<void>;
617
987
  url(): string;
988
+ request?(requests: CategoryRequest[]): Promise<CategoryGrant[]>;
618
989
  };
619
990
  declare const createFrame: (backend: FrameBackend) => Frame;
620
991
  //#endregion
992
+ //#region ../web-extension/lib/lib/frame-window.d.ts
993
+ /** `attachFrame` in both of its shapes: an iframe the app mounted, or a window it opens. */
994
+ type AttachFrameFunction = {
995
+ (options: AttachWindowOptions): Promise<WindowFrame>;
996
+ (options: AttachFrameOptions): Promise<Frame>;
997
+ };
998
+ //#endregion
621
999
  //#region ../web-extension/lib/lib/frame.d.ts
622
1000
  declare const ATTACH_FRAME_EVENT_KEY = "FKN_WEB_EXTENSION_ATTACH_FRAME_EVENT_KEY";
623
- declare const attachFrame: ({ iframe, domains, syncCookies, lockdown }: AttachFrameOptions) => Promise<Frame>;
1001
+ declare const attachFrame: AttachFrameFunction;
624
1002
  //#endregion
625
- export { OperationRequest as C, GateTools as S, isType as _, FrameBackend as a, Executor as b, attachFramePermission as c, handleRevivableModules as d, BoxedVideoElement as f, createVideoElementHandle as g, box as h, Frame as i, createFrame as l, VideoElementState as m, attachFrame as n, GotoOptions as o, RemoteVideoElement as p, AttachFrameOptions as r, Locator as s, ATTACH_FRAME_EVENT_KEY as t, gotoPermission as u, revive as v, SelectorPart as w, Gate as x, type as y };
1003
+ export { VideoElementState as A, SelectorPart as B, permissions as C, handleRevivableModules as D, PermissionCategory as E, type as F, Executor as I, Gate as L, createVideoElementHandle as M, isType as N, BoxedVideoElement as O, revive as P, GateTools as R, PermissionRequest as S, CategoryMeta as T, gotoPermission as _, AttachWindowOptions as a, LegacyPermissionRequest as b, FrameWindowBlockedError as c, FrameWindowRefusedError as d, GotoOptions as f, createFrame as g, attachFramePermission as h, AttachFrameOptions as i, box as j, RemoteVideoElement as k, FrameWindowOptions as l, WindowFrame as m, attachFrame as n, Frame as o, Locator as p, AttachFrameFunction as r, FrameBackend as s, ATTACH_FRAME_EVENT_KEY as t, FrameWindowRefusal as u, CategoryGrant as v, CATEGORIES as w, PermissionGrant as x, CategoryRequest as y, OperationRequest as z };
@@ -1,13 +1,36 @@
1
1
  import { a as WriteData$1, i as Stats, n as MakeOptions, o as WriteOptions, r as ReadOptions, t as Callback } from "./index-BQgZVQl7.js";
2
- import { r as SealedRead } from "./storage-WZEvw3KN.js";
2
+ import { d as storage_d_exports, r as SealedRead } from "./storage-ZrY4Y4L5.js";
3
3
  //#region src/fs/types.d.ts
4
+ type FileEntry = {
5
+ path: string;
6
+ size: number;
7
+ contentType: string | null;
8
+ updatedAt: string | null;
9
+ };
4
10
  type WriteData = Blob | ArrayBuffer | Uint8Array | string;
5
- //#endregion
6
- //#region src/fs/hybrid.d.ts
11
+ type FileSystem = {
12
+ available: () => Promise<boolean>;
13
+ list: () => Promise<FileEntry[]>;
14
+ readFile: (path: string) => Promise<Blob>;
15
+ writeFile: (path: string, data: WriteData, opts?: {
16
+ contentType?: string;
17
+ }) => Promise<void>;
18
+ remove: (path: string) => Promise<void>;
19
+ };
20
+ declare namespace hybrid_d_exports {
21
+ export { AdoptSummary, ConflictResolution, ConflictResolver, ConflictSide, FileConflict, FileEntry, FileSystem, WriteData, adopt$1 as adopt, adoptable$1 as adoptable, available$1 as available, list, onConflict$1 as onConflict, pending$1 as pending, pendingDeletes$1 as pendingDeletes, pull$1 as pull, readFile$1 as readFile, readFileSealed$1 as readFileSealed, remove, replicating$1 as replicating, writeFile$1 as writeFile };
22
+ }
23
+ declare const available$1: () => Promise<boolean>;
7
24
  declare const pending$1: () => string[];
8
25
  declare const pendingDeletes$1: () => string[];
9
26
  declare const replicating$1: () => boolean;
27
+ declare const list: () => Promise<FileEntry[]>;
28
+ declare const readFile$1: (path: string) => Promise<Blob>;
10
29
  declare const readFileSealed$1: (path: string) => Promise<SealedRead>;
30
+ declare const writeFile$1: (path: string, data: WriteData, opts?: {
31
+ contentType?: string;
32
+ }) => Promise<void>;
33
+ declare const remove: (path: string) => Promise<void>;
11
34
  declare const pull$1: (path: string) => Promise<Blob>;
12
35
  type AdoptSummary = {
13
36
  uploaded: string[];
package/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./rolldown-runtime-BIInC43l.cjs"),t=require("./lib-DLM2M3_i.cjs"),n=require("./api-Beky02FK.cjs"),r=require("./busy-Dv8wzE5M.cjs"),i=require("./cloud-BZmduWyX.cjs"),a=require("./dns.cjs"),o=require("./net.cjs"),s=require("./dgram.cjs"),c=require("./http.cjs"),l=require("./extension-D70dtUvW.cjs"),u=require("./desktop.cjs"),d=require("./fs-DxDxbvRS.cjs"),f=require("./opfs.cjs"),p=require("./packages.cjs"),m=require("./rooms.cjs"),h=require("./account.cjs"),g=require("./connect-button-BpXDs7tw.cjs");let _=require("osra");var v=1e4,y=150,b=()=>new Promise(e=>{if(t.F())return e(!0);let n,r=setTimeout(()=>i(t.F()),v),i=t=>{clearTimeout(n),clearTimeout(r),o.disconnect(),document.removeEventListener(`readystatechange`,s),e(t)},a=()=>{clearTimeout(n),n=setTimeout(()=>i(t.F()),y)},o=new MutationObserver(()=>{t.F()&&i(!0)}),s=()=>{document.readyState===`complete`&&!t.F()&&a()};o.observe(document.documentElement,{attributes:!0,attributeFilter:[`data-fkn-extension`]}),document.addEventListener(`readystatechange`,s),document.readyState===`complete`&&a()}),x=async e=>l.r()||e.lockdown||!i.a()||await b()?t.r(e):i.i(e),S=`https://fkn.app`,C=async(e,t)=>{if(typeof window>`u`)throw Error(`FKN @fkn/lib: relayWorker must be called from the main thread`);let i=await n.u;if(!i)throw Error(`FKN @fkn/lib: relayWorker found no FKN transport in this realm`);let a=r.t(`relayed worker`);t?.unregisterSignal?.aborted?a():t?.unregisterSignal?.addEventListener(`abort`,a,{once:!0});let o=i.emit instanceof MessagePort?{}:{originA:t?.originA??S,originB:t?.originB??`*`};(0,_.relay)(i,e,{key:`fkn-api`,...o,unregisterSignal:t?.unregisterSignal})},w=async()=>typeof window>`u`?!1:(await n.a).connect.prompt(location.origin).catch(()=>!1),T=async()=>typeof window>`u`?null:(await n.a).relay.prompt().catch(()=>null),E=new Set,D=e=>(E.add(e),()=>{E.delete(e)}),O=()=>{if(E.size===0)return!1;for(let e of[...E])try{e()}catch{}return!0},k=(e,t)=>{if(typeof e?.onUpdateTaken==`function`)return Promise.resolve(e.onUpdateTaken(t))},A=e.t({applyUpdate:()=>U,busyReasons:()=>H,onUpdate:()=>L,onUpdateTaken:()=>R,updateReady:()=>j}),j=async()=>typeof window>`u`?!1:n.a.then(e=>e.shell?.updateReady()).then(e=>e===!0).catch(()=>!1),M=new Set,N=!1,P=()=>{N=!0;for(let e of[...M])try{e()}catch{}},F=0,I=()=>{let e=n.s();!e||M.size===0||F===e.epoch||(F=e.epoch,N=!1,Promise.resolve(e.remote.shell?.onUpdate(P)).catch(()=>{F===e.epoch&&(F=0)}))};typeof window<`u`&&n.l(I);var L=async e=>{if(typeof window>`u`)return()=>{};if(M.add(e),N)try{e()}catch{}return I(),()=>{M.delete(e)}},R=e=>typeof window>`u`?()=>{}:D(e),z=0,B=!1,V=()=>{if(!O()&&!B){B=!0;try{location.reload()}catch{}}};typeof window<`u`&&n.l(()=>{let e=n.s();if(!e||z===e.epoch)return;z=e.epoch;let t=k(e.remote.shell,V);if(!t){z=0;return}t.catch(()=>{z===e.epoch&&(z=0)})});var H=()=>r.n(),U=async()=>typeof window>`u`?!1:n.a.then(e=>e.shell?.applyUpdate()).then(e=>e===!0).catch(()=>!1);exports.ATTACH_FRAME_EVENT_KEY=t.n,exports.EXTENSION_ABI=t.z,exports.ExtensionOperationUnsupportedError=t.B,exports.ExtensionOutdatedError=t.V,exports.FORGEABLE_HEADERS=t.A,exports.LOCATOR_DENIED=t.p,exports.LOCATOR_ERROR=t.g,exports.LOCATOR_UNSUPPORTED=t.u,exports.REQUIRED_EXTENSION_ABI=t.H,Object.defineProperty(exports,"account",{enumerable:!0,get:function(){return h.t}}),exports.assertAttachableFrameUrl=t.s,exports.assertFetchableUrl=t.C,exports.assertForgeableHeaders=t.j,exports.assertLockdownApplicable=t.c,exports.assertOneCookieIdentity=t.M,exports.attachFrame=x,exports.attachFramePermission=t.i,exports.box=t.G,Object.defineProperty(exports,"cloud",{enumerable:!0,get:function(){return i.n}}),exports.connect=w,exports.connectButtonUrl=g.t,exports.cookies=t.x,exports.createFrame=t.a,exports.createVideoElementHandle=t.K,Object.defineProperty(exports,"desktop",{enumerable:!0,get:function(){return u.t}}),Object.defineProperty(exports,"dgram",{enumerable:!0,get:function(){return s.t}}),Object.defineProperty(exports,"dns",{enumerable:!0,get:function(){return a.t}}),Object.defineProperty(exports,"extension",{enumerable:!0,get:function(){return l.t}}),exports.fetch=l.n,exports.fetchCredentialedPermission=t.T,exports.fetchLocalPermission=t.E,exports.fetchPermission=t.D,Object.defineProperty(exports,"fs",{enumerable:!0,get:function(){return d.u}}),exports.gotoPermission=t.o,exports.handleRevivableModules=t.W,exports.hasForgedCookie=t.N,Object.defineProperty(exports,"http",{enumerable:!0,get:function(){return c.t}}),exports.isBlockedFetchUrl=t.O,exports.isBlockedFrameUrl=t.l,exports.isExtensionExposed=t.F,exports.isLocalNetworkUrl=t.k,exports.isLocatorDenied=t.h,exports.isLocatorUnsupported=t._,exports.isTerminalError=t.f,exports.isType=t.q,exports.modifyRequestHeadersPermission=t.v,Object.defineProperty(exports,"net",{enumerable:!0,get:function(){return o.t}}),Object.defineProperty(exports,"opfs",{enumerable:!0,get:function(){return f.t}}),Object.defineProperty(exports,"packages",{enumerable:!0,get:function(){return p.t}}),exports.permissions=t.t,exports.promptInstall=l.i,exports.promptRelay=T,exports.readCookiePermission=t.S,exports.readExtensionHandshake=t.I,exports.relayWorker=C,exports.removeRequestHeaderRule=t.y,exports.revive=t.J,Object.defineProperty(exports,"rooms",{enumerable:!0,get:function(){return m.t}}),exports.setMissingExtensionHandler=t.L,exports.setRequestHeaderRule=t.b,Object.defineProperty(exports,"shell",{enumerable:!0,get:function(){return A}}),exports.supportsOperation=t.U,exports.type=t.Y,exports.waitForExtensionExposure=t.R;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./rolldown-runtime-BIInC43l.cjs"),t=require("./lib-Cjd91q7g.cjs"),n=require("./api-Djf-XdZ4.cjs"),r=require("./busy-Dv8wzE5M.cjs"),i=require("./cloud-DCWD_0sd.cjs"),a=require("./dns.cjs"),o=require("./net.cjs"),s=require("./dgram.cjs"),c=require("./http.cjs"),l=require("./extension-DSrUjoLw.cjs"),u=require("./desktop.cjs"),d=require("./fs-D8RCGFNc.cjs"),f=require("./opfs.cjs"),p=require("./packages.cjs"),m=require("./rooms.cjs"),h=require("./account.cjs"),g=require("./connect-button-BpXDs7tw.cjs");let _=require("osra");var v=1e4,y=150,b=()=>new Promise(e=>{if(t.G())return e(!0);let n,r=setTimeout(()=>i(t.G()),v),i=t=>{clearTimeout(n),clearTimeout(r),o.disconnect(),document.removeEventListener(`readystatechange`,s),e(t)},a=()=>{clearTimeout(n),n=setTimeout(()=>i(t.G()),y)},o=new MutationObserver(()=>{t.G()&&i(!0)}),s=()=>{document.readyState===`complete`&&!t.G()&&a()};o.observe(document.documentElement,{attributes:!0,attributeFilter:[`data-fkn-extension`]}),document.addEventListener(`readystatechange`,s),document.readyState===`complete`&&a()}),x=(async e=>{if(t.o(e)===`window`){let n=e;return l.r()?t.a(n):i.a()?i.i(n):t.a(n)}return S(e)}),S=async e=>l.r()||e.lockdown||!i.a()||await b()?t.a(e):i.i(e),C=`https://fkn.app`,w=async(e,t)=>{if(typeof window>`u`)throw Error(`FKN @fkn/lib: relayWorker must be called from the main thread`);let i=await n.u;if(!i)throw Error(`FKN @fkn/lib: relayWorker found no FKN transport in this realm`);let a=r.t(`relayed worker`);t?.unregisterSignal?.aborted?a():t?.unregisterSignal?.addEventListener(`abort`,a,{once:!0});let o=i.emit instanceof MessagePort?{}:{originA:t?.originA??C,originB:t?.originB??`*`};(0,_.relay)(i,e,{key:`fkn-api`,...o,unregisterSignal:t?.unregisterSignal})},T=async()=>typeof window>`u`?!1:(await n.a).connect.prompt(location.origin).catch(()=>!1),E=async()=>typeof window>`u`?null:(await n.a).relay.prompt().catch(()=>null),D=new Set,O=e=>(D.add(e),()=>{D.delete(e)}),k=()=>{if(D.size===0)return!1;for(let e of[...D])try{e()}catch{}return!0},A=(e,t)=>{if(typeof e?.onUpdateTaken==`function`)return Promise.resolve(e.onUpdateTaken(t))},j=e.t({applyUpdate:()=>W,busyReasons:()=>U,onUpdate:()=>R,onUpdateTaken:()=>z,updateReady:()=>M}),M=async()=>typeof window>`u`?!1:n.a.then(e=>e.shell?.updateReady()).then(e=>e===!0).catch(()=>!1),N=new Set,P=!1,F=()=>{P=!0;for(let e of[...N])try{e()}catch{}},I=0,L=()=>{let e=n.s();e&&N.size!==0&&I!==e.epoch&&(I=e.epoch,P=!1,Promise.resolve(e.remote.shell?.onUpdate(F)).catch(()=>{I===e.epoch&&(I=0)}))};typeof window<`u`&&n.l(L);var R=async e=>{if(typeof window>`u`)return()=>{};if(N.add(e),P)try{e()}catch{}return L(),()=>{N.delete(e)}},z=e=>typeof window>`u`?()=>{}:O(e),B=0,V=!1,H=()=>{if(!k()&&!V){V=!0;try{location.reload()}catch{}}};typeof window<`u`&&n.l(()=>{let e=n.s();if(!e||B===e.epoch)return;B=e.epoch;let t=A(e.remote.shell,H);if(!t){B=0;return}t.catch(()=>{B===e.epoch&&(B=0)})});var U=()=>r.n(),W=async()=>typeof window>`u`?!1:n.a.then(e=>e.shell?.applyUpdate()).then(e=>e===!0).catch(()=>!1);exports.ATTACH_FRAME_EVENT_KEY=t.i,exports.CATEGORIES=t.D,exports.EXTENSION_ABI=t.Y,exports.ExtensionOperationUnsupportedError=t.X,exports.ExtensionOutdatedError=t.Z,exports.FORGEABLE_HEADERS=t.B,exports.FrameWindowBlockedError=t.d,exports.FrameWindowRefusedError=t.f,exports.LOCATOR_DENIED=t.C,exports.LOCATOR_ERROR=t.E,exports.LOCATOR_UNSUPPORTED=t.b,exports.PERMISSION_DENIED=t.t,exports.REQUIRED_EXTENSION_ABI=t.Q,Object.defineProperty(exports,"account",{enumerable:!0,get:function(){return h.t}}),exports.assertAttachableFrameUrl=t.g,exports.assertFetchableUrl=t.N,exports.assertForgeableHeaders=t.V,exports.assertLockdownApplicable=t._,exports.assertOneCookieIdentity=t.H,exports.attachFrame=x,exports.attachFramePermission=t.p,exports.box=t.tt,Object.defineProperty(exports,"cloud",{enumerable:!0,get:function(){return i.n}}),exports.connect=T,exports.connectButtonUrl=g.t,exports.cookies=t.j,exports.createFrame=t.m,exports.createVideoElementHandle=t.nt,Object.defineProperty(exports,"desktop",{enumerable:!0,get:function(){return u.t}}),Object.defineProperty(exports,"dgram",{enumerable:!0,get:function(){return s.t}}),Object.defineProperty(exports,"dns",{enumerable:!0,get:function(){return a.t}}),Object.defineProperty(exports,"extension",{enumerable:!0,get:function(){return l.t}}),exports.fetch=l.n,exports.fetchCredentialedPermission=t.F,exports.fetchLocalPermission=t.I,exports.fetchPermission=t.L,Object.defineProperty(exports,"fs",{enumerable:!0,get:function(){return d.u}}),exports.gotoPermission=t.h,exports.handleRevivableModules=t.et,exports.hasForgedCookie=t.U,Object.defineProperty(exports,"http",{enumerable:!0,get:function(){return c.t}}),exports.isBlockedFetchUrl=t.R,exports.isBlockedFrameUrl=t.v,exports.isExtensionExposed=t.G,exports.isLocalNetworkUrl=t.z,exports.isLocatorDenied=t.y,exports.isLocatorUnsupported=t.S,exports.isPermissionDenied=t.n,exports.isTerminalError=t.T,exports.isType=t.rt,exports.modifyRequestHeadersPermission=t.O,Object.defineProperty(exports,"net",{enumerable:!0,get:function(){return o.t}}),Object.defineProperty(exports,"opfs",{enumerable:!0,get:function(){return f.t}}),Object.defineProperty(exports,"packages",{enumerable:!0,get:function(){return p.t}}),exports.permissions=t.r,exports.promptInstall=l.i,exports.promptRelay=E,exports.readCookiePermission=t.M,exports.readExtensionHandshake=t.K,exports.relayWorker=w,exports.removeRequestHeaderRule=t.k,exports.revive=t.it,Object.defineProperty(exports,"rooms",{enumerable:!0,get:function(){return m.t}}),exports.setMissingExtensionHandler=t.q,exports.setRequestHeaderRule=t.A,Object.defineProperty(exports,"shell",{enumerable:!0,get:function(){return j}}),exports.supportsOperation=t.$,exports.type=t.at,exports.waitForExtensionExposure=t.J;
package/index.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import { t as account_d_exports } from "./account.js";
2
- import { A as modifyRequestHeadersPermission, C as LOCATOR_ERROR, D as isTerminalError, E as isLocatorUnsupported, F as cookies, G as isLocalNetworkUrl, H as fetchLocalPermission, I as readCookiePermission, J as assertOneCookieIdentity, K as FORGEABLE_HEADERS, L as FetchInit, M as setRequestHeaderRule, N as CookieDetails, O as HeaderOperation, P as SiteCookie, R as ProxyFetchRequest, S as LOCATOR_DENIED, T as isLocatorDenied, U as fetchPermission, V as fetchCredentialedPermission, W as isBlockedFetchUrl, Y as hasForgedCookie, _ as PermissionRequest, b as assertLockdownApplicable, c as setMissingExtensionHandler, d as ExtensionHandshake, f as ExtensionOperationUnsupportedError, g as PermissionGrant, h as supportsOperation, i as promptInstall, j as removeRequestHeaderRule, k as RequestHeaderRule, l as waitForExtensionExposure, m as REQUIRED_EXTENSION_ABI, n as fetch, o as isExtensionExposed, p as ExtensionOutdatedError, q as assertForgeableHeaders, s as readExtensionHandshake, t as extension_d_exports, u as EXTENSION_ABI, v as permissions, w as LOCATOR_UNSUPPORTED, x as isBlockedFrameUrl, y as assertAttachableFrameUrl, z as assertFetchableUrl } from "./extension-DNkuFy1Y.js";
3
- import { C as OperationRequest, S as GateTools, _ as isType, a as FrameBackend, b as Executor, c as attachFramePermission, d as handleRevivableModules, f as BoxedVideoElement, g as createVideoElementHandle, h as box, i as Frame, l as createFrame, m as VideoElementState, o as GotoOptions, p as RemoteVideoElement, r as AttachFrameOptions, s as Locator, t as ATTACH_FRAME_EVENT_KEY, u as gotoPermission, v as revive, w as SelectorPart, x as Gate, y as type } from "./index-DH3_12nU.js";
4
- import { n as cloud_d_exports } from "./cloud-D0Ebu5bX.js";
2
+ import { A as VideoElementState, B as SelectorPart, C as permissions, D as handleRevivableModules, E as PermissionCategory, F as type, I as Executor, L as Gate, M as createVideoElementHandle, N as isType, O as BoxedVideoElement, P as revive, R as GateTools, S as PermissionRequest, T as CategoryMeta, _ as gotoPermission, a as AttachWindowOptions, b as LegacyPermissionRequest, c as FrameWindowBlockedError, d as FrameWindowRefusedError, f as GotoOptions, g as createFrame, h as attachFramePermission, i as AttachFrameOptions, j as box, k as RemoteVideoElement, l as FrameWindowOptions, m as WindowFrame, o as Frame, p as Locator, r as AttachFrameFunction, s as FrameBackend, t as ATTACH_FRAME_EVENT_KEY, u as FrameWindowRefusal, v as CategoryGrant, w as CATEGORIES, x as PermissionGrant, y as CategoryRequest, z as OperationRequest } from "./index-C_Lqta5o.js";
3
+ import { A as readCookiePermission, B as FORGEABLE_HEADERS, C as RequestHeaderRule, D as CookieDetails, E as setRequestHeaderRule, F as fetchCredentialedPermission, G as LOCATOR_ERROR, H as assertOneCookieIdentity, I as fetchLocalPermission, J as isLocatorUnsupported, K as LOCATOR_UNSUPPORTED, L as fetchPermission, M as ProxyFetchRequest, N as assertFetchableUrl, O as SiteCookie, R as isBlockedFetchUrl, S as HeaderOperation, T as removeRequestHeaderRule, U as hasForgedCookie, V as assertForgeableHeaders, W as LOCATOR_DENIED, Y as isTerminalError, _ as PermissionDeniedError, b as assertLockdownApplicable, c as setMissingExtensionHandler, d as ExtensionHandshake, f as ExtensionOperationUnsupportedError, g as PERMISSION_DENIED, h as supportsOperation, i as promptInstall, j as FetchInit, k as cookies, l as waitForExtensionExposure, m as REQUIRED_EXTENSION_ABI, n as fetch, o as isExtensionExposed, p as ExtensionOutdatedError, q as isLocatorDenied, s as readExtensionHandshake, t as extension_d_exports, u as EXTENSION_ABI, v as isPermissionDenied, w as modifyRequestHeadersPermission, x as isBlockedFrameUrl, y as assertAttachableFrameUrl, z as isLocalNetworkUrl } from "./extension-TRYu_aG-.js";
4
+ import { n as cloud_d_exports } from "./cloud-DxitkM7z.js";
5
5
  import { t as dns_d_exports } from "./dns.js";
6
- import { u as index_d_exports } from "./index-Cg6y_FTi.js";
7
- import { s as net_d_exports } from "./net-BXPEJToS.js";
6
+ import { u as index_d_exports } from "./index-kuPqkS_-.js";
7
+ import { s as net_d_exports } from "./net-0SlODFSM.js";
8
8
  import { t as dgram_d_exports } from "./dgram.js";
9
9
  import { t as http_d_exports } from "./http.js";
10
10
  import { t as desktop_d_exports } from "./desktop.js";
@@ -13,20 +13,35 @@ import { t as packages_d_exports } from "./packages.js";
13
13
  import { t as rooms_d_exports } from "./rooms.js";
14
14
  import { t as connectButtonUrl } from "./connect-button-Cp0NS95-.js";
15
15
  //#region src/frame.d.ts
16
- declare const attachFrame: (options: AttachFrameOptions) => Promise<Frame>;
16
+ /**
17
+ * Attaches FKN to an iframe the app mounted, on the extension when it is installed and on the cloud
18
+ * render proxy otherwise, or with `{ window }` opens the attachment in a window of its own.
19
+ *
20
+ * A window opens before the first await, so call this directly in the click or key handler whose
21
+ * activation opens it. It never waits for the extension to expose itself: a click lands on a loaded
22
+ * page, where the extension has exposed itself or never will.
23
+ *
24
+ * In this release only the cloud backend serves a window. With the extension installed, a window
25
+ * is refused at once with `ExtensionOperationUnsupportedError` (operation `'attachWindow'`), before
26
+ * anything opens or is waited for, so the same click can still open one with
27
+ * `cloud.attachFrame({ window })`. That window runs on this app's cloud cookie jar, not on the
28
+ * extension's: a sign-in made in it reaches this app's cloud frames, never an iframe attached
29
+ * through the extension.
30
+ */
31
+ export declare const attachFrame: AttachFrameFunction;
17
32
  //#endregion
18
33
  //#region src/relay.d.ts
19
- declare const relayWorker: (worker: Worker, options?: {
34
+ export declare const relayWorker: (worker: Worker, options?: {
20
35
  unregisterSignal?: AbortSignal;
21
36
  originA?: string;
22
37
  originB?: string;
23
38
  }) => Promise<void>;
24
39
  //#endregion
25
40
  //#region src/connect.d.ts
26
- declare const connect: () => Promise<boolean>;
41
+ export declare const connect: () => Promise<boolean>;
27
42
  //#endregion
28
43
  //#region src/relay-prompt.d.ts
29
- declare const promptRelay: () => Promise<string | null>;
44
+ export declare const promptRelay: () => Promise<string | null>;
30
45
  declare namespace shell_d_exports {
31
46
  export { applyUpdate, busyReasons, onUpdate, onUpdateTaken, updateReady };
32
47
  }
@@ -111,4 +126,4 @@ declare const busyReasons: () => string[];
111
126
  */
112
127
  declare const applyUpdate: () => Promise<boolean>;
113
128
  //#endregion
114
- export { ATTACH_FRAME_EVENT_KEY, AttachFrameOptions, BoxedVideoElement, CookieDetails, EXTENSION_ABI, type Executor, type ExtensionHandshake, ExtensionOperationUnsupportedError, ExtensionOutdatedError, FORGEABLE_HEADERS, FetchInit, Frame, FrameBackend, type Gate, type GateTools, GotoOptions, HeaderOperation, LOCATOR_DENIED, LOCATOR_ERROR, LOCATOR_UNSUPPORTED, Locator, type OperationRequest, PermissionGrant, PermissionRequest, ProxyFetchRequest, REQUIRED_EXTENSION_ABI, RemoteVideoElement, RequestHeaderRule, type SelectorPart, SiteCookie, VideoElementState, account_d_exports as account, assertAttachableFrameUrl, assertFetchableUrl, assertForgeableHeaders, assertLockdownApplicable, assertOneCookieIdentity, attachFrame, attachFramePermission, box, cloud_d_exports as cloud, connect, connectButtonUrl, cookies, createFrame, createVideoElementHandle, desktop_d_exports as desktop, dgram_d_exports as dgram, dns_d_exports as dns, extension_d_exports as extension, fetch, fetchCredentialedPermission, fetchLocalPermission, fetchPermission, index_d_exports as fs, gotoPermission, handleRevivableModules, hasForgedCookie, http_d_exports as http, isBlockedFetchUrl, isBlockedFrameUrl, isExtensionExposed, isLocalNetworkUrl, isLocatorDenied, isLocatorUnsupported, isTerminalError, isType, modifyRequestHeadersPermission, net_d_exports as net, index_d_exports$1 as opfs, packages_d_exports as packages, permissions, promptInstall, promptRelay, readCookiePermission, readExtensionHandshake, relayWorker, removeRequestHeaderRule, revive, rooms_d_exports as rooms, setMissingExtensionHandler, setRequestHeaderRule, shell_d_exports as shell, supportsOperation, type, waitForExtensionExposure };
129
+ export { ATTACH_FRAME_EVENT_KEY, AttachFrameOptions, AttachWindowOptions, BoxedVideoElement, CATEGORIES, CategoryGrant, type CategoryMeta, CategoryRequest, CookieDetails, EXTENSION_ABI, type Executor, type ExtensionHandshake, ExtensionOperationUnsupportedError, ExtensionOutdatedError, FORGEABLE_HEADERS, FetchInit, Frame, FrameBackend, FrameWindowBlockedError, FrameWindowOptions, FrameWindowRefusal, FrameWindowRefusedError, type Gate, type GateTools, GotoOptions, HeaderOperation, LOCATOR_DENIED, LOCATOR_ERROR, LOCATOR_UNSUPPORTED, LegacyPermissionRequest, Locator, type OperationRequest, PERMISSION_DENIED, type PermissionCategory, type PermissionDeniedError, PermissionGrant, PermissionRequest, ProxyFetchRequest, REQUIRED_EXTENSION_ABI, RemoteVideoElement, RequestHeaderRule, type SelectorPart, SiteCookie, VideoElementState, WindowFrame, account_d_exports as account, assertAttachableFrameUrl, assertFetchableUrl, assertForgeableHeaders, assertLockdownApplicable, assertOneCookieIdentity, attachFramePermission, box, cloud_d_exports as cloud, connectButtonUrl, cookies, createFrame, createVideoElementHandle, desktop_d_exports as desktop, dgram_d_exports as dgram, dns_d_exports as dns, extension_d_exports as extension, fetch, fetchCredentialedPermission, fetchLocalPermission, fetchPermission, index_d_exports as fs, gotoPermission, handleRevivableModules, hasForgedCookie, http_d_exports as http, isBlockedFetchUrl, isBlockedFrameUrl, isExtensionExposed, isLocalNetworkUrl, isLocatorDenied, isLocatorUnsupported, isPermissionDenied, isTerminalError, isType, modifyRequestHeadersPermission, net_d_exports as net, index_d_exports$1 as opfs, packages_d_exports as packages, permissions, promptInstall, readCookiePermission, readExtensionHandshake, removeRequestHeaderRule, revive, rooms_d_exports as rooms, setMissingExtensionHandler, setRequestHeaderRule, shell_d_exports as shell, supportsOperation, type, waitForExtensionExposure };