@jxsuite/studio 3.0.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (197) hide show
  1. package/README.md +5 -5
  2. package/dist/chunks/{2020-xp8vnwma.js → 2020-n6tfwnda.js} +2 -2
  3. package/dist/chunks/Overlay.dev-etqjwyf9.js +23 -0
  4. package/dist/chunks/cf-account-picker-en86v7x7.js +163 -0
  5. package/dist/chunks/{cf-settings-zj2cj1ar.js → cf-settings-45fgyx8y.js} +6 -5
  6. package/dist/chunks/{components-z6cnkyy1.js → components-zmx10t62.js} +6 -5
  7. package/dist/chunks/content-source-48xg86wj.js +49 -0
  8. package/dist/chunks/{convert-to-repeater-6vvx96n2.js → convert-to-repeater-43tfn7cs.js} +33 -25
  9. package/dist/chunks/entry-commands-e63f1xc0.js +46 -0
  10. package/dist/chunks/{extension-sections-kwzvpemr.js → extension-sections-txv08xxg.js} +34 -26
  11. package/dist/chunks/file-ops-wbh4hhsx.js +48 -0
  12. package/dist/chunks/files-3kfkwhk4.js +93 -0
  13. package/dist/chunks/{focus-trap.esm-ggawf1hy.js → focus-trap.esm-9t2drp0g.js} +6 -5
  14. package/dist/chunks/{format-host-8fr3545e.js → format-host-w16q81tf.js} +3 -3
  15. package/dist/chunks/fs-events-hrrg328g.js +21 -0
  16. package/dist/chunks/{git-panel-g01d93vc.js → git-panel-532whr1y.js} +22 -16
  17. package/dist/chunks/{index-nj44jpzj.js → index-wcnt3r9g.js} +2 -2
  18. package/dist/chunks/{jx-validate-jj9rnt4n.js → jx-validate-8er6gbxy.js} +6 -4
  19. package/dist/chunks/layers-panel-07hm7g5j.js +67 -0
  20. package/dist/chunks/layers-q75tj2mf.js +45 -0
  21. package/dist/chunks/lit-html-j055mkh8.js +22 -0
  22. package/dist/chunks/monaco-buffer-dqw0xxpx.js +25 -0
  23. package/dist/chunks/{monaco-setup-a5wkmbgh.js → monaco-setup-vx9bhp1d.js} +4 -4
  24. package/dist/chunks/notify-yjm79n4s.js +30 -0
  25. package/dist/chunks/parse-24d0gay3.js +19 -0
  26. package/dist/chunks/platform-ba1j1gbh.js +16 -0
  27. package/dist/chunks/publish-panel-v9st96ja.js +29 -0
  28. package/dist/chunks/quick-search-zccjp6gv.js +66 -0
  29. package/dist/chunks/references-3qx8fkyp.js +29 -0
  30. package/dist/chunks/right-panel-vm3b6kwy.js +46 -0
  31. package/dist/chunks/sp-overlay.dev-qgvhnxf4.js +18 -0
  32. package/dist/chunks/sp-popover.dev-n2etmqdp.js +9 -0
  33. package/dist/chunks/sp-progress-circle.dev-hryhj0es.js +15 -0
  34. package/dist/chunks/sp-tooltip.dev-4sastdnw.js +15 -0
  35. package/dist/chunks/{sp-tray.dev-64v4pxw8.js → sp-tray.dev-tkbscm06.js} +5 -5
  36. package/dist/chunks/{studio-wdt9y92a.js → studio-0bq6eh7v.js} +2 -2
  37. package/dist/chunks/studio-1ngbejft.js +181 -0
  38. package/dist/chunks/studio-1wagb550.js +118 -0
  39. package/dist/chunks/{studio-j595e748.js → studio-2b946z26.js} +172 -95
  40. package/dist/chunks/{studio-pkp61mh8.js → studio-3bqpr0zh.js} +25 -17
  41. package/dist/chunks/{studio-k4jvjcfx.js → studio-4b5z1x43.js} +46 -12
  42. package/dist/chunks/{studio-ry1vz5sv.js → studio-4n2b5gzb.js} +15 -13
  43. package/dist/chunks/{studio-p5dja96s.js → studio-4r1pv6zf.js} +2 -2
  44. package/dist/chunks/{studio-kvfx9z2c.js → studio-4rzyrtjz.js} +70 -31
  45. package/dist/chunks/{studio-tzx3xmvx.js → studio-5fx3g9jg.js} +33 -52
  46. package/dist/chunks/{studio-rh1cnamv.js → studio-5myknm0a.js} +565 -135
  47. package/dist/chunks/studio-6yw4y3my.js +91 -0
  48. package/dist/chunks/{studio-0rqqhrdy.js → studio-7nte2hj4.js} +2 -2
  49. package/dist/chunks/studio-92ab2jqe.js +282 -0
  50. package/dist/chunks/{studio-6z5eyjwn.js → studio-950k0dx6.js} +72 -135
  51. package/dist/chunks/{studio-sas7mt3k.js → studio-9ab8gqsm.js} +2 -2
  52. package/dist/chunks/studio-9n4mrmnb.js +184 -0
  53. package/dist/chunks/{studio-hcxzyk3x.js → studio-ahn3pdgx.js} +6 -6
  54. package/dist/chunks/studio-b55y6ewx.js +498 -0
  55. package/dist/chunks/{studio-s519zc99.js → studio-bgxt93ga.js} +3 -3
  56. package/dist/chunks/studio-cft9r4r7.js +119 -0
  57. package/dist/chunks/{studio-dc8s8heb.js → studio-cmb03bg5.js} +6904 -8321
  58. package/dist/chunks/studio-dm19q43r.js +195 -0
  59. package/dist/chunks/{studio-2x9zbxmx.js → studio-ef49pnzx.js} +11 -9
  60. package/dist/chunks/{studio-ay8wcr2b.js → studio-eqq1w638.js} +7 -9
  61. package/dist/chunks/{studio-5efrtn1m.js → studio-ew0djmhg.js} +23 -19
  62. package/dist/chunks/{studio-tr20m8g8.js → studio-f3wqjtk5.js} +39 -3
  63. package/dist/chunks/{studio-xntfdy1x.js → studio-fbf92ckf.js} +36 -23
  64. package/dist/chunks/{studio-4q0wznzf.js → studio-gcye7qka.js} +442 -126
  65. package/dist/chunks/{studio-7p35254k.js → studio-gfgb8pe6.js} +36 -193
  66. package/dist/chunks/studio-jc994dnr.js +1066 -0
  67. package/dist/chunks/{studio-hj2se583.js → studio-jkftxyvz.js} +69 -3423
  68. package/dist/chunks/{studio-5x5774ak.js → studio-kryvsw6j.js} +3 -3
  69. package/dist/chunks/{studio-kfpek536.js → studio-kyh9avvv.js} +2 -2
  70. package/dist/chunks/{studio-twsafr1e.js → studio-m3hwn7y1.js} +3 -3
  71. package/dist/chunks/studio-msd847zn.js +1315 -0
  72. package/dist/chunks/{studio-g5gdqnyd.js → studio-mtfnaqs9.js} +19 -19
  73. package/dist/chunks/{studio-7ejemhej.js → studio-n6j9t10q.js} +6 -6
  74. package/dist/chunks/{studio-vhk5fmfv.js → studio-n8b9wqwy.js} +5 -5
  75. package/dist/chunks/{studio-cjm7fdjf.js → studio-p4ngc046.js} +8 -104
  76. package/dist/chunks/studio-q43a5y9h.js +394 -0
  77. package/dist/chunks/studio-q7v10cg2.js +106 -0
  78. package/dist/chunks/{studio-6kv3apa9.js → studio-q9jd1a60.js} +27 -11
  79. package/dist/chunks/studio-qcy05dp8.js +1743 -0
  80. package/dist/chunks/{studio-a0yp7syn.js → studio-qjy2z9bv.js} +29 -132
  81. package/dist/chunks/{studio-2w11grav.js → studio-qq6jym04.js} +3 -3
  82. package/dist/chunks/{studio-3fk1ac9z.js → studio-rdx8jcxy.js} +4 -4
  83. package/dist/chunks/{studio-4mqb9a0j.js → studio-rn9ta2mz.js} +4 -4
  84. package/dist/chunks/studio-t7qb9db8.js +665 -0
  85. package/dist/chunks/studio-tmc5emrw.js +8 -0
  86. package/dist/chunks/{studio-r5xbtctf.js → studio-trxrabqf.js} +292 -2297
  87. package/dist/chunks/studio-wcy8trfx.js +263 -0
  88. package/dist/chunks/{studio-3dkcd4c5.js → studio-x4qkdat5.js} +62 -57
  89. package/dist/chunks/studio-x813zp48.js +195 -0
  90. package/dist/chunks/{studio-qpfq7xhm.js → studio-xrapxwwc.js} +22 -285
  91. package/dist/chunks/{studio-xm3dbxvn.js → studio-zczps70q.js} +2 -2
  92. package/dist/chunks/{studio-8ezdegcx.js → studio-zqazsct2.js} +40 -36
  93. package/dist/chunks/workspace-fjx52ryv.js +89 -0
  94. package/dist/iframe-entry.js +141 -56
  95. package/dist/manifest.json +7 -0
  96. package/dist/studio.js +2605 -1950
  97. package/favicon.ico +0 -0
  98. package/index.html +1 -0
  99. package/package.json +20 -18
  100. package/src/about/about-modal.ts +4 -3
  101. package/src/browse/library-pane.ts +57 -3
  102. package/src/canvas/canvas-render.ts +23 -1
  103. package/src/canvas/iframe-patch.ts +47 -21
  104. package/src/canvas/iframe-render.ts +22 -6
  105. package/src/commands/app-commands.ts +4 -0
  106. package/src/commands/command-args.ts +29 -0
  107. package/src/commands/context.ts +15 -1
  108. package/src/commands/defaults.ts +29 -1
  109. package/src/commands/levels.ts +16 -0
  110. package/src/commands/live-context.ts +3 -0
  111. package/src/content/collection-match.ts +267 -0
  112. package/src/content/entry-commands.ts +38 -29
  113. package/src/content/entry-fields.ts +6 -0
  114. package/src/editor/shortcuts.ts +5 -0
  115. package/src/files/file-ops.ts +10 -42
  116. package/src/files/files.ts +487 -59
  117. package/src/files/fs-events.ts +9 -0
  118. package/src/files/gitignore.ts +432 -0
  119. package/src/files/media-paths.ts +13 -42
  120. package/src/files/media-usage.ts +41 -131
  121. package/src/files/serialize-document.ts +60 -0
  122. package/src/format/convert-file.ts +511 -0
  123. package/src/format/format-choices.ts +199 -0
  124. package/src/grid/grid-view.ts +16 -2
  125. package/src/hosting/document.ts +2 -0
  126. package/src/hosting/layout.ts +8 -0
  127. package/src/media/media-open.ts +58 -0
  128. package/src/media/media-pane.ts +310 -0
  129. package/src/new-project/import-tab.ts +357 -163
  130. package/src/new-project/location-fields.ts +8 -5
  131. package/src/new-project/new-project-modal.ts +27 -34
  132. package/src/packages/ensure-deps.ts +14 -7
  133. package/src/packages/jxsuite-update.ts +11 -11
  134. package/src/page-params.ts +10 -46
  135. package/src/panels/activity-bar.ts +45 -16
  136. package/src/panels/ai-chat/attached-context.ts +6 -1
  137. package/src/panels/ai-chat/chat-view.ts +255 -13
  138. package/src/panels/ai-chat/composer.ts +31 -97
  139. package/src/panels/ai-panel.ts +116 -2
  140. package/src/panels/navigator-panels.ts +7 -6
  141. package/src/panels/settings-menu.ts +799 -0
  142. package/src/panels/toolbar.ts +135 -15
  143. package/src/platforms/cloud.ts +261 -70
  144. package/src/platforms/devserver.ts +67 -33
  145. package/src/preview/preview-overlay.ts +226 -0
  146. package/src/publish/publish-panel.ts +62 -2
  147. package/src/services/ai-ask.ts +247 -0
  148. package/src/services/ai-import-tools.ts +532 -0
  149. package/src/services/ai-models.ts +108 -1
  150. package/src/services/ai-project-tools.ts +20 -26
  151. package/src/services/ai-system-prompt.ts +88 -2
  152. package/src/services/ai-turn-signal.ts +70 -0
  153. package/src/services/connection.ts +74 -0
  154. package/src/services/context-manager.ts +101 -1
  155. package/src/services/document-assistant.ts +45 -4
  156. package/src/services/import-client.ts +33 -6
  157. package/src/services/import-run.ts +158 -0
  158. package/src/services/import-seed.ts +120 -0
  159. package/src/services/jx-validate.ts +58 -6
  160. package/src/services/project-adoption.ts +71 -0
  161. package/src/services/references.ts +0 -0
  162. package/src/services/settings/definitions.ts +17 -0
  163. package/src/services/tool-executor.ts +45 -2
  164. package/src/settings/contexts-section.ts +45 -3
  165. package/src/settings/dependencies-editor.ts +43 -23
  166. package/src/settings/general-settings.ts +30 -12
  167. package/src/settings/preferences-accounts.ts +193 -12
  168. package/src/settings/preferences-dialog.ts +93 -59
  169. package/src/settings/preferences-sections.ts +57 -0
  170. package/src/settings/settings-document.ts +65 -9
  171. package/src/studio.ts +33 -6
  172. package/src/tabs/transact.ts +42 -19
  173. package/src/types.ts +129 -7
  174. package/src/ui/ai-managed-connect.ts +62 -13
  175. package/src/ui/ai-model-picker.ts +189 -0
  176. package/src/ui/cf-account-picker.ts +200 -0
  177. package/src/ui/choice-field.ts +72 -0
  178. package/src/ui/layers.ts +83 -5
  179. package/src/utils/studio-utils.ts +22 -52
  180. package/styles/forced-colors.css +7 -0
  181. package/styles/overlays.css +256 -0
  182. package/styles/panels.css +13 -1
  183. package/styles/shell.css +147 -0
  184. package/dist/chunks/Overlay.dev-d2ajy6sj.js +0 -23
  185. package/dist/chunks/content-source-7fy9qrm0.js +0 -40
  186. package/dist/chunks/files-xcybanxe.js +0 -70
  187. package/dist/chunks/layers-panel-27essgkc.js +0 -60
  188. package/dist/chunks/publish-panel-09sy2bab.js +0 -22
  189. package/dist/chunks/quick-search-sefb61v8.js +0 -55
  190. package/dist/chunks/right-panel-9r32jd5j.js +0 -39
  191. package/dist/chunks/sp-overlay.dev-s18hymn9.js +0 -18
  192. package/dist/chunks/sp-popover.dev-dj9x7e7a.js +0 -9
  193. package/dist/chunks/sp-progress-circle.dev-0zxcyz3r.js +0 -15
  194. package/dist/chunks/sp-tooltip.dev-5c6d1kjz.js +0 -15
  195. package/dist/chunks/studio-bw5dz6km.js +0 -608
  196. package/dist/chunks/studio-c31yb4t6.js +0 -55
  197. package/src/canvas/site-style-css.ts +0 -117
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  MatchMediaController,
3
3
  modal_css_default
4
- } from "./studio-4mqb9a0j.js";
4
+ } from "./studio-rn9ta2mz.js";
5
5
  import {
6
6
  firstFocusableIn
7
7
  } from "./studio-z6nw2ek2.js";
@@ -14,14 +14,14 @@ import {
14
14
  property,
15
15
  query,
16
16
  state
17
- } from "./studio-xm3dbxvn.js";
17
+ } from "./studio-zczps70q.js";
18
18
  import {
19
19
  css
20
- } from "./studio-0rqqhrdy.js";
20
+ } from "./studio-7nte2hj4.js";
21
21
  import {
22
22
  html,
23
23
  nothing
24
- } from "./studio-5x5774ak.js";
24
+ } from "./studio-kryvsw6j.js";
25
25
  import"./studio-a0tswy0w.js";
26
26
 
27
27
  // ../../node_modules/@spectrum-web-components/tray/src/tray.css.js
@@ -196,4 +196,4 @@ __decorateClass([
196
196
  defineElement("sp-tray", Tray);
197
197
 
198
198
  //# debugId=1815636C6C9940AB64756E2164756E21
199
- //# sourceMappingURL=sp-tray.dev-64v4pxw8.js.map
199
+ //# sourceMappingURL=sp-tray.dev-tkbscm06.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Overlay
3
- } from "./studio-tzx3xmvx.js";
3
+ } from "./studio-5fx3g9jg.js";
4
4
  import {
5
5
  defineElement
6
6
  } from "./studio-18j3bmcz.js";
@@ -9,4 +9,4 @@ import {
9
9
  defineElement("sp-overlay", Overlay);
10
10
 
11
11
  //# debugId=24A9645EA10C33DD64756E2164756E21
12
- //# sourceMappingURL=studio-wdt9y92a.js.map
12
+ //# sourceMappingURL=studio-0bq6eh7v.js.map
@@ -0,0 +1,181 @@
1
+ import {
2
+ showDialog
3
+ } from "./studio-t7qb9db8.js";
4
+ import {
5
+ errorMessage
6
+ } from "./studio-9n4mrmnb.js";
7
+ import {
8
+ notify
9
+ } from "./studio-xrapxwwc.js";
10
+ import {
11
+ html
12
+ } from "./studio-kryvsw6j.js";
13
+
14
+ // src/github/github-auth.ts
15
+ var CLIENT_ID = "Ov23liYVlMFpgjOEPXJH";
16
+ var STORAGE_KEY = "jx_github_token";
17
+ function nativeAuth() {
18
+ return globalThis.__jxPlatform?.githubAuth ?? null;
19
+ }
20
+ var nativeToken = null;
21
+ var nativeStored = false;
22
+ function githubTokenStored() {
23
+ return nativeToken !== null || nativeStored || localStorage.getItem(STORAGE_KEY) !== null;
24
+ }
25
+ function githubTokenLocation() {
26
+ return nativeAuth() ? "desktop" : "browser";
27
+ }
28
+ var NOTIFY_KEY = "github.auth";
29
+ var SOURCE = "Source Control";
30
+ var RETRY = "git.signInToGithub";
31
+ var MAX_POLL_FAILURES = 3;
32
+ var UNREACHABLE_DETAIL = "The request never reached GitHub. GitHub's device-flow endpoints send no CORS headers, so a " + "browser cannot call them directly — the desktop app can. A machine that is offline fails " + "identically, and the browser does not say which happened.";
33
+ function getGithubToken() {
34
+ return nativeToken ?? localStorage.getItem(STORAGE_KEY);
35
+ }
36
+ function clearGithubToken() {
37
+ nativeToken = null;
38
+ nativeStored = false;
39
+ localStorage.removeItem(STORAGE_KEY);
40
+ nativeAuth()?.signOut().catch(() => {});
41
+ }
42
+ function reportUnreachable(error) {
43
+ notify.error("Could not reach GitHub to sign in.", {
44
+ action: RETRY,
45
+ detail: `${UNREACHABLE_DETAIL}
46
+
47
+ ${errorMessage(error)}`,
48
+ key: NOTIFY_KEY,
49
+ source: SOURCE
50
+ });
51
+ }
52
+ function reportRefused(message, detail) {
53
+ notify.warn(message, { action: RETRY, detail, key: NOTIFY_KEY, source: SOURCE });
54
+ }
55
+ async function requestDeviceCode() {
56
+ let codeRes;
57
+ try {
58
+ codeRes = await fetch("https://github.com/login/device/code", {
59
+ body: JSON.stringify({ client_id: CLIENT_ID, scope: "repo" }),
60
+ headers: {
61
+ Accept: "application/json",
62
+ "Content-Type": "application/json"
63
+ },
64
+ method: "POST"
65
+ });
66
+ } catch (error) {
67
+ reportUnreachable(error);
68
+ return null;
69
+ }
70
+ if (!codeRes.ok) {
71
+ reportRefused("GitHub refused to start the sign-in.", `GitHub answered ${codeRes.status}${codeRes.statusText ? ` ${codeRes.statusText}` : ""}.`);
72
+ return null;
73
+ }
74
+ return await codeRes.json();
75
+ }
76
+ async function authenticateGithub() {
77
+ const existing = getGithubToken();
78
+ if (existing) {
79
+ return existing;
80
+ }
81
+ const native = nativeAuth();
82
+ if (native) {
83
+ try {
84
+ const { token } = await native.signIn();
85
+ nativeToken = token;
86
+ return token;
87
+ } catch (error) {
88
+ reportRefused("GitHub sign-in was not completed.", errorMessage(error));
89
+ return null;
90
+ }
91
+ }
92
+ const codeData = await requestDeviceCode();
93
+ if (!codeData) {
94
+ return null;
95
+ }
96
+ const { device_code, user_code, verification_uri, interval = 5 } = codeData;
97
+ return showDialog((done) => {
98
+ let cancelled = false;
99
+ let pollTimer = null;
100
+ let failures = 0;
101
+ const stop = () => {
102
+ cancelled = true;
103
+ if (pollTimer) {
104
+ clearTimeout(pollTimer);
105
+ }
106
+ done(null);
107
+ };
108
+ const poll = async () => {
109
+ if (cancelled) {
110
+ return;
111
+ }
112
+ try {
113
+ const tokenRes = await fetch("https://github.com/login/oauth/access_token", {
114
+ body: JSON.stringify({
115
+ client_id: CLIENT_ID,
116
+ device_code,
117
+ grant_type: "urn:ietf:params:oauth:grant-type:device_code"
118
+ }),
119
+ headers: {
120
+ Accept: "application/json",
121
+ "Content-Type": "application/json"
122
+ },
123
+ method: "POST"
124
+ });
125
+ const tokenData = await tokenRes.json();
126
+ failures = 0;
127
+ if (tokenData.access_token) {
128
+ localStorage.setItem(STORAGE_KEY, tokenData.access_token);
129
+ done(tokenData.access_token);
130
+ return;
131
+ }
132
+ if (tokenData.error === "authorization_pending") {
133
+ pollTimer = setTimeout(poll, interval * 1000);
134
+ return;
135
+ }
136
+ if (tokenData.error === "slow_down") {
137
+ pollTimer = setTimeout(poll, (interval + 5) * 1000);
138
+ return;
139
+ }
140
+ reportRefused("GitHub sign-in was not completed.", tokenData.error === "access_denied" ? "The authorization was declined on GitHub." : tokenData.error === "expired_token" ? "The device code expired before it was entered." : `GitHub answered "${tokenData.error ?? "an unrecognised response"}".`);
141
+ cancelled = true;
142
+ done(null);
143
+ } catch (error) {
144
+ failures += 1;
145
+ if (failures >= MAX_POLL_FAILURES) {
146
+ reportUnreachable(error);
147
+ cancelled = true;
148
+ done(null);
149
+ return;
150
+ }
151
+ pollTimer = setTimeout(poll, interval * 1000);
152
+ }
153
+ };
154
+ pollTimer = setTimeout(poll, interval * 1000);
155
+ return html`
156
+ <sp-dialog-wrapper
157
+ open
158
+ headline="Sign in to GitHub"
159
+ cancel-label="Cancel"
160
+ @cancel=${stop}
161
+ @close=${stop}
162
+ >
163
+ <div class="github-auth-dialog">
164
+ <p>Enter this code on GitHub to authorize Jx Studio:</p>
165
+ <div class="github-auth-code">${user_code}</div>
166
+ <p>
167
+ <a href="${verification_uri}" target="_blank" rel="noopener"
168
+ >Open ${verification_uri}</a
169
+ >
170
+ </p>
171
+ <p class="github-auth-waiting">Waiting for authorization…</p>
172
+ </div>
173
+ </sp-dialog-wrapper>
174
+ `;
175
+ });
176
+ }
177
+
178
+ export { githubTokenStored, githubTokenLocation, clearGithubToken, authenticateGithub };
179
+
180
+ //# debugId=0BF996D0D429B90564756E2164756E21
181
+ //# sourceMappingURL=studio-1ngbejft.js.map
@@ -0,0 +1,118 @@
1
+ import {
2
+ baseName,
3
+ dirName,
4
+ extensionOf,
5
+ mediaKind
6
+ } from "./studio-qjy2z9bv.js";
7
+ import {
8
+ normalizeProjectPath
9
+ } from "./studio-2b946z26.js";
10
+ import {
11
+ getPlatform
12
+ } from "./studio-9ab8gqsm.js";
13
+
14
+ // src/files/media-meta.ts
15
+ var settled = new Map;
16
+ var inFlight = new Map;
17
+ var measured = new Map;
18
+ function metaFrom(path, entry) {
19
+ const name = baseName(path);
20
+ const dims = measured.get(path);
21
+ return {
22
+ bytes: typeof entry?.size === "number" ? entry.size : null,
23
+ ext: extensionOf(name),
24
+ height: dims?.height ?? null,
25
+ kind: mediaKind({ name }),
26
+ modified: entry?.modified ?? null,
27
+ name,
28
+ path,
29
+ width: dims?.width ?? null
30
+ };
31
+ }
32
+ function peekMediaMeta(path) {
33
+ return settled.get(normalizeProjectPath(path)) ?? null;
34
+ }
35
+ function seedMediaMeta(entries) {
36
+ for (const entry of entries) {
37
+ if (entry.type !== "file") {
38
+ continue;
39
+ }
40
+ const path = normalizeProjectPath(entry.path);
41
+ if (!settled.has(path)) {
42
+ settled.set(path, metaFrom(path, entry));
43
+ }
44
+ }
45
+ }
46
+ async function loadMediaMeta(path) {
47
+ const key = normalizeProjectPath(path);
48
+ const done = settled.get(key);
49
+ if (done) {
50
+ return done;
51
+ }
52
+ const running = inFlight.get(key);
53
+ if (running) {
54
+ return running;
55
+ }
56
+ const pending = (async () => {
57
+ let entry;
58
+ try {
59
+ const listing = await getPlatform().listDirectory(dirName(key));
60
+ entry = listing.find((item) => normalizeProjectPath(item.path) === key);
61
+ } catch {
62
+ entry = undefined;
63
+ }
64
+ return metaFrom(key, entry);
65
+ })();
66
+ inFlight.set(key, pending);
67
+ const meta = await pending;
68
+ inFlight.delete(key);
69
+ settled.set(key, meta);
70
+ return meta;
71
+ }
72
+ function recordImageSize(path, width, height) {
73
+ if (!(width > 0 && height > 0)) {
74
+ return false;
75
+ }
76
+ const key = normalizeProjectPath(path);
77
+ const known = measured.get(key);
78
+ if (known && known.width === width && known.height === height) {
79
+ return false;
80
+ }
81
+ measured.set(key, { height, width });
82
+ const meta = settled.get(key);
83
+ if (meta) {
84
+ settled.set(key, { ...meta, height, width });
85
+ }
86
+ return true;
87
+ }
88
+ function invalidateMediaMeta() {
89
+ settled.clear();
90
+ measured.clear();
91
+ }
92
+ function formatBytes(bytes) {
93
+ if (bytes < 1024) {
94
+ return `${bytes} B`;
95
+ }
96
+ if (bytes < 1024 * 1024) {
97
+ return `${Math.round(bytes / 1024)} KB`;
98
+ }
99
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
100
+ }
101
+ function mediaMetaSummary(meta) {
102
+ if (!meta) {
103
+ return "";
104
+ }
105
+ const parts = [];
106
+ if (meta.width !== null && meta.height !== null) {
107
+ parts.push(`${meta.width} × ${meta.height}`);
108
+ }
109
+ if (meta.bytes !== null) {
110
+ parts.push(formatBytes(meta.bytes));
111
+ }
112
+ return parts.join(" · ");
113
+ }
114
+
115
+ export { peekMediaMeta, seedMediaMeta, loadMediaMeta, recordImageSize, invalidateMediaMeta, formatBytes, mediaMetaSummary };
116
+
117
+ //# debugId=18B99161AAFC90A064756E2164756E21
118
+ //# sourceMappingURL=studio-1wagb550.js.map