@hyperframes/studio 0.8.19 → 0.8.20
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/assets/{hyperframes-player-BA-QO9CQ.js → hyperframes-player-BEKxuimO.js} +1 -1
- package/dist/assets/{index-Dd0fsIIL.js → index-BL1zYTW0.js} +1 -1
- package/dist/assets/{index-Bjd2hioj.js → index-CBSKXKAr.js} +118 -118
- package/dist/assets/{index-DxccOrkZ.js → index-Cehosfnu.js} +1 -1
- package/dist/index.html +1 -1
- package/dist/index.js +36 -7
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/src/hooks/useEditorSave.test.tsx +81 -3
- package/src/hooks/useEditorSave.ts +31 -6
- package/src/hooks/useGsapInteractionFailureTelemetry.test.tsx +48 -16
- package/src/hooks/useGsapInteractionFailureTelemetry.ts +5 -2
- package/src/utils/studioFileVersion.test.ts +37 -1
- package/src/utils/studioFileVersion.ts +12 -2
- package/src/utils/studioSaveDiagnostics.test.ts +29 -0
- package/src/utils/studioSaveDiagnostics.ts +4 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as P}from"./index-
|
|
1
|
+
import{g as P}from"./index-CBSKXKAr.js";function j(c,d){for(var s=0;s<d.length;s++){const a=d[s];if(typeof a!="string"&&!Array.isArray(a)){for(const i in a)if(i!=="default"&&!(i in c)){const l=Object.getOwnPropertyDescriptor(a,i);l&&Object.defineProperty(c,i,l.get?l:{enumerable:!0,get:()=>a[i]})}}}return Object.freeze(Object.defineProperty(c,Symbol.toStringTag,{value:"Module"}))}var v={},w;function k(){if(w)return v;w=1,Object.defineProperty(v,"__esModule",{value:!0}),v.default=d;var c=window.OfflineAudioContext||window.webkitOfflineAudioContext;function d(e){var r=a(e);return r.start(0),[i,y,O(e.sampleRate),s].reduce(function(t,o){return o(t)},r.buffer.getChannelData(0))}function s(e){return e.sort(function(r,t){return t.count-r.count}).splice(0,5)[0].tempo}function a(e){var r=e.length,t=e.numberOfChannels,o=e.sampleRate,n=new c(t,r,o),u=n.createBufferSource();u.buffer=e;var f=n.createBiquadFilter();return f.type="lowpass",u.connect(f),f.connect(n.destination),u}function i(e){for(var r=[],t=.9,o=.3,n=15;r.length<n&&t>=o;)r=l(e,t),t-=.05;if(r.length<n)throw new Error("Could not find enough samples for a reliable detection.");return r}function l(e,r){for(var t=[],o=0,n=e.length;o<n;o+=1)e[o]>r&&(t.push(o),o+=1e4);return t}function y(e){var r=[];return e.forEach(function(t,o){for(var n=function(x){var g=e[o+x]-t,_=r.some(function(h){if(h.interval===g)return h.count+=1});_||r.push({interval:g,count:1})},u=0;u<10;u+=1)n(u)}),r}function O(e){return function(r){var t=[];return r.forEach(function(o){if(o.interval!==0){for(var n=60/(o.interval/e);n<90;)n*=2;for(;n>180;)n/=2;n=Math.round(n);var u=t.some(function(f){if(f.tempo===n)return f.count+=o.count});u||t.push({tempo:n,count:o.count})}}),t}}return v}var p,b;function q(){return b||(b=1,p=k().default),p}var m=q();const A=P(m),D=j({__proto__:null,default:A},[m]);export{D as i};
|
package/dist/index.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
|
6
6
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
7
7
|
<title>HyperFrames Studio</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-CBSKXKAr.js"></script>
|
|
9
9
|
<link rel="stylesheet" crossorigin href="/assets/index-yGhfxxoL.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
package/dist/index.js
CHANGED
|
@@ -16306,6 +16306,9 @@ function buildStudioSaveFailureProperties(input) {
|
|
|
16306
16306
|
function trackStudioSaveFailure(input) {
|
|
16307
16307
|
trackStudioEvent("save_failure", buildStudioSaveFailureProperties(input));
|
|
16308
16308
|
}
|
|
16309
|
+
function trackStudioEditBlocked(input) {
|
|
16310
|
+
trackStudioEvent("edit_blocked", buildStudioSaveFailureProperties(input));
|
|
16311
|
+
}
|
|
16309
16312
|
async function createStudioSaveHttpError(response, fallbackMessage, options = {}) {
|
|
16310
16313
|
let body = "";
|
|
16311
16314
|
try {
|
|
@@ -16693,7 +16696,16 @@ async function studioExpectedFileVersion(versions, path, expectedContent) {
|
|
|
16693
16696
|
return versions.get(path);
|
|
16694
16697
|
}
|
|
16695
16698
|
function createStudioWriteToken() {
|
|
16696
|
-
|
|
16699
|
+
const webCrypto = globalThis.crypto;
|
|
16700
|
+
if (typeof webCrypto?.randomUUID === "function") return webCrypto.randomUUID();
|
|
16701
|
+
if (typeof webCrypto?.getRandomValues !== "function") {
|
|
16702
|
+
throw new Error("Web Crypto getRandomValues is required for Studio write identity");
|
|
16703
|
+
}
|
|
16704
|
+
const bytes = webCrypto.getRandomValues(new Uint8Array(16));
|
|
16705
|
+
bytes[6] = bytes[6] & 15 | 64;
|
|
16706
|
+
bytes[8] = bytes[8] & 63 | 128;
|
|
16707
|
+
const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
16708
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
16697
16709
|
}
|
|
16698
16710
|
function studioWriteHeaders() {
|
|
16699
16711
|
const token = createStudioWriteToken();
|
|
@@ -62928,6 +62940,7 @@ function useFileTree({ projectId, projectIdRef }) {
|
|
|
62928
62940
|
|
|
62929
62941
|
// src/hooks/useEditorSave.ts
|
|
62930
62942
|
import { useCallback as useCallback87, useRef as useRef112 } from "react";
|
|
62943
|
+
var FAILURE_BURST_MS = 5e3;
|
|
62931
62944
|
function useEditorSave({
|
|
62932
62945
|
editingPathRef,
|
|
62933
62946
|
projectIdRef,
|
|
@@ -62940,18 +62953,32 @@ function useEditorSave({
|
|
|
62940
62953
|
}) {
|
|
62941
62954
|
const saveRafRef = useRef112(null);
|
|
62942
62955
|
const refreshRafRef = useRef112(null);
|
|
62943
|
-
const lastFailureToastAtRef = useRef112(
|
|
62956
|
+
const lastFailureToastAtRef = useRef112(null);
|
|
62957
|
+
const lastFailureReportRef = useRef112(null);
|
|
62944
62958
|
const pendingCandidateRef = useRef112(null);
|
|
62945
62959
|
const inFlightRef = useRef112(null);
|
|
62946
62960
|
const inFlightCandidateRef = useRef112(null);
|
|
62947
62961
|
const reportFailure = useCallback87(
|
|
62948
62962
|
(path, error) => {
|
|
62949
|
-
|
|
62963
|
+
const now2 = Date.now();
|
|
62964
|
+
const properties = buildStudioSaveFailureProperties({
|
|
62950
62965
|
source: "code_editor",
|
|
62951
|
-
|
|
62966
|
+
error,
|
|
62967
|
+
filePath: path
|
|
62952
62968
|
});
|
|
62953
|
-
const
|
|
62954
|
-
|
|
62969
|
+
const errorName = error instanceof Error ? error.name : typeof error;
|
|
62970
|
+
const fingerprint = JSON.stringify([
|
|
62971
|
+
path,
|
|
62972
|
+
errorName,
|
|
62973
|
+
properties.error_message,
|
|
62974
|
+
properties.status_code
|
|
62975
|
+
]);
|
|
62976
|
+
const previous = lastFailureReportRef.current;
|
|
62977
|
+
if (previous === null || previous.fingerprint !== fingerprint || now2 - previous.emittedAt >= FAILURE_BURST_MS) {
|
|
62978
|
+
trackStudioSaveFailure({ source: "code_editor", error, filePath: path });
|
|
62979
|
+
lastFailureReportRef.current = { fingerprint, emittedAt: now2 };
|
|
62980
|
+
}
|
|
62981
|
+
if (lastFailureToastAtRef.current === null || now2 - lastFailureToastAtRef.current >= FAILURE_BURST_MS) {
|
|
62955
62982
|
lastFailureToastAtRef.current = now2;
|
|
62956
62983
|
showToast(
|
|
62957
62984
|
`Couldn't save ${path} \u2014 your latest edits are NOT persisted. Check the preview server; editing again retries the save.`,
|
|
@@ -62974,6 +63001,7 @@ function useEditorSave({
|
|
|
62974
63001
|
recordEdit
|
|
62975
63002
|
}).then(() => {
|
|
62976
63003
|
if (pendingCandidateRef.current === candidate) pendingCandidateRef.current = null;
|
|
63004
|
+
lastFailureReportRef.current = null;
|
|
62977
63005
|
if (refreshRafRef.current != null) cancelAnimationFrame(refreshRafRef.current);
|
|
62978
63006
|
refreshRafRef.current = requestAnimationFrame(() => setRefreshKey((k) => k + 1));
|
|
62979
63007
|
return { status: "clean" };
|
|
@@ -70189,7 +70217,8 @@ import { useCallback as useCallback117 } from "react";
|
|
|
70189
70217
|
function useGsapInteractionFailureTelemetry(activeCompPath, showToast) {
|
|
70190
70218
|
return useCallback117(
|
|
70191
70219
|
(error, selection, mutationType, label) => {
|
|
70192
|
-
trackStudioSaveFailure
|
|
70220
|
+
const report = isGsapEditBlockedError(error) ? trackStudioEditBlocked : trackStudioSaveFailure;
|
|
70221
|
+
report({
|
|
70193
70222
|
source: "gsap_commit",
|
|
70194
70223
|
error,
|
|
70195
70224
|
filePath: selection?.sourceFile ?? activeCompPath ?? "index.html",
|