Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@sanity/preview-kit-compat

Package Overview
Dependencies
Maintainers
56
Versions
148
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@sanity/preview-kit-compat - npm Package Compare versions

Comparing version 1.5.5 to 1.5.6-canary.1

14

CHANGELOG.md

@@ -39,2 +39,16 @@ <!-- markdownlint-disable --><!-- textlint-disable -->

## [1.5.6](https://github.com/sanity-io/visual-editing/compare/preview-kit-compat-v1.5.5...preview-kit-compat-v1.5.6) (2024-08-12)
### Bug Fixes
* **deps:** update dependency @sanity/client to v6.21.2 ([#1749](https://github.com/sanity-io/visual-editing/issues/1749)) ([b9efdd2](https://github.com/sanity-io/visual-editing/commit/b9efdd2a672fdef518bc22a29a25992c938ba1ef))
### Dependencies
* The following workspace dependencies were updated
* devDependencies
* @repo/visual-editing-helpers bumped to 0.6.20
## [1.5.5](https://github.com/sanity-io/visual-editing/compare/preview-kit-compat-v1.5.4...preview-kit-compat-v1.5.5) (2024-08-02)

@@ -41,0 +55,0 @@

323

dist/index.js

@@ -1,1 +0,322 @@

import{useState as e,useEffect as n,useMemo as t,useSyncExternalStore as o,useCallback as i}from"react";let r;const s=new Uint8Array(16);function a(){if(!r&&(r=typeof crypto<"u"&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto),!r))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return r(s)}const c=[];for(let e=0;e<256;++e)c.push((e+256).toString(16).slice(1));var d={randomUUID:typeof crypto<"u"&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};function u(e,n,t){if(d.randomUUID&&!n&&!e)return d.randomUUID();const o=(e=e||{}).random||(e.rng||a)();return o[6]=15&o[6]|64,o[8]=63&o[8]|128,function(e,n=0){return c[e[n+0]]+c[e[n+1]]+c[e[n+2]]+c[e[n+3]]+"-"+c[e[n+4]]+c[e[n+5]]+"-"+c[e[n+6]]+c[e[n+7]]+"-"+c[e[n+8]]+c[e[n+9]]+"-"+c[e[n+10]]+c[e[n+11]]+c[e[n+12]]+c[e[n+13]]+c[e[n+14]]+c[e[n+15]]}(o)}const f=["channel/disconnect","channel/response","channel/heartbeat"],l=["handshake/syn","handshake/syn-ack","handshake/ack"],p=e=>f.some((n=>n===e)),h=e=>l.some((n=>n===e)),y=({data:e={}})=>"object"==typeof e&&null!==e&&!Array.isArray(e)&&!("domain"in e)&&["id","type","from","to"].every((n=>n in e))&&e.type.startsWith("handshake/");function m(e){const n=window.self!==window.top||window.opener,t={buffer:[],id:null,origin:null,source:null,status:"connecting"};function o(n,o){if(h(n)||p(n)||"connecting"!==t.status&&"reconnecting"!==t.status){if(t.id&&t.origin&&t.source){const i={connectionId:t.id,data:o,domain:"sanity/channels",from:e.id,id:u(),to:e.connectTo,type:n};try{t.source.postMessage(i,{targetOrigin:t.origin})}catch{throw new Error(`Failed to postMessage '${i.id}' on '${e.id}'`)}}}else t.buffer.push({type:n,data:o})}function i(n){if(y(n))console.error("Visual editing package mismatch detected! Please ensure you are using the latest version of Sanity Studio and any packages listed here:\nhttps://github.com/sanity-io/visual-editing");else if(function(n){const{data:t}=n;return"sanity/channels"===t.domain&&t.to===e.id&&t.from===e.connectTo&&"channel/response"!==t.type}(n)){const{data:e}=n;if(t.origin&&n.origin!==t.origin)return;if(n.source&&t.source!==n.source&&(t.source=n.source),h(e.type)&&e.data){if("handshake/syn"===e.type)return t.origin=n.origin,t.id=e.data.id,a("connecting"),void o("handshake/syn-ack",{id:t.id});if("handshake/ack"===e.type&&e.data.id===t.id)return void a("connected")}else if(e.connectionId===t.id&&n.origin===t.origin){if("channel/disconnect"===e.type)return void a("disconnected");{const n=[e.type,e.data];r.forEach((e=>{e(...n)})),o("channel/response",{responseTo:e.id})}return}}}const r=new Set;const s=new Set;function a(e){t.status=e,s.forEach((n=>{n(e)})),"connected"===e&&function(){const e=[...t.buffer];t.buffer.splice(0,t.buffer.length),e.forEach((({type:e,data:n})=>{o(e,n)}))}()}return window.addEventListener("message",i,!1),a("connecting"),{destroy:function(){["disconnected"].includes(t.status)||a("disconnected"),r.clear(),s.clear(),window.removeEventListener("message",i,!1)},inFrame:n,send:function(e,n){o(e,n)},subscribe:function(e){return r.add(e),()=>r.delete(e)},onStatusUpdate:function(e){return s.add(e),()=>s.delete(e)}}}function g(t,o,i){const[r,s]=e(),[a,c]=e(!1);n((()=>{if(window.self===window.top&&!window.opener)return;const e=m({id:"preview-kit",connectTo:"presentation"});e.onStatusUpdate((e=>{"connected"===e?c(!0):"disconnected"===e&&c(!1)}));const n=setTimeout((()=>s(e)),0);return()=>{clearTimeout(n),e.destroy(),s(void 0)}}),[i,o]);const d=JSON.stringify(Array.from(t.keys()));n((()=>{"[]"!==d&&r&&a&&r.send("preview-kit/documents",{projectId:o,dataset:i,perspective:"previewDrafts",documents:Array.from(t.values())})}),[d,r,a,i,t,o])}function w(e){const n=t((()=>JSON.stringify(e||{})),[e]);return t((()=>JSON.parse(n)),[n])}function v(t){const{refreshInterval:r}=t,s=function(){const[t,i]=e(!1);n((()=>{i(navigator.onLine);const e=()=>i(!0),n=()=>i(!1);return window.addEventListener("online",e),window.addEventListener("offline",n),()=>{window.removeEventListener("online",e),window.removeEventListener("offline",n)}}),[]);const r=o(b,(()=>document.visibilityState),(()=>"hidden"));return!t||"hidden"===r}(),[a,c]=e("hit"),d=i((()=>(c("inflight"),()=>c("hit"))),[]);return n((()=>{if(!r||"hit"!==a)return;const e=setTimeout((()=>c("stale")),r);return()=>clearTimeout(e)}),[r,a]),n((()=>{if("hit"!==a)return;const e=()=>c("stale");return window.addEventListener("focus",e),()=>window.removeEventListener("focus",e)}),[r,a]),n((()=>{s&&"hit"===a&&c("stale"),!s&&"stale"===a&&c("refresh")}),[s,a]),[a,d]}function b(e){return document.addEventListener("visibilitychange",e),()=>document.removeEventListener("visibilitychange",e)}export{g as useDocumentsInUse,w as useQueryParams,v as useRevalidate};//# sourceMappingURL=index.js.map
import { useState, useEffect, useMemo, useCallback, useSyncExternalStore } from 'react';
/**
* Convert array of 16 byte values to UUID string format of the form:
* XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
*/
var byteToHex = [];
for (var i = 0; i < 256; ++i) {
byteToHex.push((i + 0x100).toString(16).slice(1));
}
function unsafeStringify(arr, offset = 0) {
// Note: Be careful editing this code! It's been tuned for performance
// and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
//
// Note to future-self: No, you can't remove the `toLowerCase()` call.
// REF: https://github.com/uuidjs/uuid/pull/677#issuecomment-1757351351
return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
}
// Unique ID creation requires a high quality random # generator. In the browser we therefore
// require the crypto API and do not support built-in fallback to lower quality random number
// generators (like Math.random()).
var getRandomValues;
var rnds8 = new Uint8Array(16);
function rng() {
// lazy load so that environments that need to polyfill have a chance to do so
if (!getRandomValues) {
// getRandomValues needs to be invoked in a context where "this" is a Crypto implementation.
getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto);
if (!getRandomValues) {
throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
}
}
return getRandomValues(rnds8);
}
var randomUUID = typeof crypto !== 'undefined' && crypto.randomUUID && crypto.randomUUID.bind(crypto);
var native = {
randomUUID
};
function v4(options, buf, offset) {
if (native.randomUUID && !buf && !options) {
return native.randomUUID();
}
options = options || {};
var rnds = options.random || (options.rng || rng)();
// Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
rnds[6] = rnds[6] & 0x0f | 0x40;
rnds[8] = rnds[8] & 0x3f | 0x80;
return unsafeStringify(rnds);
}
const INTERNAL_MSG_TYPES = [
"channel/disconnect",
"channel/response",
"channel/heartbeat"
];
const HANDSHAKE_MSG_TYPES = [
"handshake/syn",
"handshake/syn-ack",
"handshake/ack"
];
const isInternalMessage = (type) => {
return INTERNAL_MSG_TYPES.some((t) => t === type);
};
const isHandshakeMessage = (type) => {
return HANDSHAKE_MSG_TYPES.some((t) => t === type);
};
const isLegacyHandshakeMessage = ({ data = {} }) => {
return (
// Check data is a record type
typeof data === "object" && data !== null && !Array.isArray(data) && // The "domain" key was introduced in commit 4854e7f
!("domain" in data) && // Check the rest of the object shape is present
["id", "type", "from", "to"].every((key) => key in data) && // Prior to 4854e7f only handshake events were emitted prior to an established connection
data.type.startsWith("handshake/")
);
};
function createChannelsNode(config) {
const inFrame = window.self !== window.top || window.opener;
const channel = {
buffer: [],
id: null,
origin: null,
source: null,
status: "connecting"
};
function flush() {
const toFlush = [...channel.buffer];
channel.buffer.splice(0, channel.buffer.length);
toFlush.forEach(({ type, data }) => {
send(type, data);
});
}
function send(type, data) {
if (!isHandshakeMessage(type) && !isInternalMessage(type) && (channel.status === "connecting" || channel.status === "reconnecting")) {
channel.buffer.push({ type, data });
return;
}
if (channel.id && channel.origin && channel.source) {
const msg = {
connectionId: channel.id,
data,
domain: "sanity/channels",
from: config.id,
id: v4(),
to: config.connectTo,
type
};
try {
channel.source.postMessage(msg, {
targetOrigin: channel.origin
});
} catch (e) {
throw new Error(`Failed to postMessage '${msg.id}' on '${config.id}'`);
}
}
}
function isValidMessageEvent(e) {
const { data } = e;
return data.domain === "sanity/channels" && data.to === config.id && data.from === config.connectTo && data.type !== "channel/response";
}
function handleEvents(e) {
if (isLegacyHandshakeMessage(e)) {
console.error(
"Visual editing package mismatch detected! Please ensure you are using the latest version of Sanity Studio and any packages listed here:\nhttps://github.com/sanity-io/visual-editing"
);
return;
}
if (isValidMessageEvent(e)) {
const { data } = e;
if (channel.origin && e.origin !== channel.origin) {
return;
}
if (e.source && channel.source !== e.source) {
channel.source = e.source;
}
if (isHandshakeMessage(data.type) && data.data) {
if (data.type === "handshake/syn") {
channel.origin = e.origin;
channel.id = data.data["id"];
setConnectionStatus("connecting");
send("handshake/syn-ack", { id: channel.id });
return;
}
if (data.type === "handshake/ack" && data.data["id"] === channel.id) {
setConnectionStatus("connected");
return;
}
} else if (data.connectionId === channel.id && e.origin === channel.origin) {
if (data.type === "channel/disconnect") {
setConnectionStatus("disconnected");
return;
} else {
const args = [data.type, data.data];
eventSubscribers.forEach((subscriber) => {
subscriber(...args);
});
send("channel/response", { responseTo: data.id });
}
return;
}
}
}
const eventSubscribers = /* @__PURE__ */ new Set();
function subscribeToEvent(subscriber) {
eventSubscribers.add(subscriber);
return () => eventSubscribers.delete(subscriber);
}
function disconnect() {
if (["disconnected"].includes(channel.status)) return;
setConnectionStatus("disconnected");
}
const statusSubscribers = /* @__PURE__ */ new Set();
function subscribeToStatus(subscriber) {
statusSubscribers.add(subscriber);
return () => statusSubscribers.delete(subscriber);
}
function setConnectionStatus(next) {
channel.status = next;
statusSubscribers.forEach((subscriber) => {
subscriber(next);
});
if (next === "connected") {
flush();
}
}
function destroy() {
disconnect();
eventSubscribers.clear();
statusSubscribers.clear();
window.removeEventListener("message", handleEvents, false);
}
function initialise() {
window.addEventListener("message", handleEvents, false);
setConnectionStatus("connecting");
}
initialise();
function sendPublic(type, data) {
send(type, data);
}
return {
destroy,
inFrame,
send: sendPublic,
subscribe: subscribeToEvent,
onStatusUpdate: subscribeToStatus
};
}
function useDocumentsInUse(documentsInUse, projectId, dataset) {
const [channel, setChannel] = useState();
const [connected, setConnected] = useState(false);
useEffect(() => {
if (window.self === window.top && !window.opener) {
return;
}
const channel2 = createChannelsNode({
id: "preview-kit",
connectTo: "presentation"
});
channel2.onStatusUpdate((status) => {
if (status === "connected") {
setConnected(true);
} else if (status === "disconnected") {
setConnected(false);
}
});
const timeout = setTimeout(() => setChannel(channel2), 0);
return () => {
clearTimeout(timeout);
channel2.destroy();
setChannel(void 0);
};
}, [dataset, projectId]);
const changedKeys = JSON.stringify(Array.from(documentsInUse.keys()));
useEffect(() => {
if (changedKeys !== "[]" && channel && connected) {
channel.send("preview-kit/documents", {
projectId,
dataset,
perspective: "previewDrafts",
documents: Array.from(documentsInUse.values())
});
}
}, [changedKeys, channel, connected, dataset, documentsInUse, projectId]);
}
function useQueryParams(params) {
const stringifiedParams = useMemo(() => JSON.stringify(params || {}), [params]);
return useMemo(() => JSON.parse(stringifiedParams), [stringifiedParams]);
}
function useRevalidate(props) {
const { refreshInterval } = props;
const shouldPause = useShouldPause();
const [state, setState] = useState("hit");
const startRefresh = useCallback(() => {
setState("inflight");
return () => setState("hit");
}, []);
useEffect(() => {
if (!refreshInterval || state !== "hit") {
return;
}
const timeout = setTimeout(() => setState("stale"), refreshInterval);
return () => clearTimeout(timeout);
}, [refreshInterval, state]);
useEffect(() => {
if (state !== "hit") {
return;
}
const onFocus = () => setState("stale");
window.addEventListener("focus", onFocus);
return () => window.removeEventListener("focus", onFocus);
}, [refreshInterval, state]);
useEffect(() => {
if (shouldPause && state === "hit") {
setState("stale");
}
if (!shouldPause && state === "stale") {
setState("refresh");
}
}, [shouldPause, state]);
return [state, startRefresh];
}
function useShouldPause() {
const [online, setOnline] = useState(false);
useEffect(() => {
setOnline(navigator.onLine);
const online2 = () => setOnline(true);
const offline = () => setOnline(false);
window.addEventListener("online", online2);
window.addEventListener("offline", offline);
return () => {
window.removeEventListener("online", online2);
window.removeEventListener("offline", offline);
};
}, []);
const visibilityState = useSyncExternalStore(
onVisibilityChange,
() => document.visibilityState,
() => "hidden"
);
if (!online) {
return true;
}
if (visibilityState === "hidden") {
return true;
}
return false;
}
function onVisibilityChange(onStoreChange) {
document.addEventListener("visibilitychange", onStoreChange);
return () => document.removeEventListener("visibilitychange", onStoreChange);
}
export { useDocumentsInUse, useQueryParams, useRevalidate };
//# sourceMappingURL=index.js.map

32

package.json
{
"name": "@sanity/preview-kit-compat",
"version": "1.5.5",
"version": "1.5.6-canary.1",
"homepage": "https://github.com/sanity-io/visual-editing/tree/main/packages/preview-kit-compat#readme",

@@ -91,20 +91,20 @@ "bugs": {

"devDependencies": {
"@repo/channels": "0.4.0",
"@repo/visual-editing-helpers": "0.6.19",
"@sanity/client": "^6.21.1",
"@sanity/pkg-utils": "6.9.3",
"@types/react": "^18.3.3",
"@typescript-eslint/eslint-plugin": "^7.13.1",
"@typescript-eslint/parser": "^7.13.1",
"@sanity/client": "^6.21.3",
"@sanity/pkg-utils": "6.11.1",
"@types/react": "^18.3.5",
"@typescript-eslint/eslint-plugin": "^7.18.0",
"@typescript-eslint/parser": "^7.18.0",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-simple-import-sort": "^12.1.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-simple-import-sort": "^12.1.1",
"react": "^18.3.1",
"typescript": "5.4.5",
"vitest": "^1.6.0",
"@repo/package.config": "0.0.0"
"typescript": "5.6.2",
"vitest": "^2.0.5",
"@repo/channels": "0.4.0",
"@repo/package.config": "0.0.0",
"@repo/visual-editing-helpers": "0.6.20"
},
"peerDependencies": {
"@sanity/client": "^6.21.1",
"@sanity/client": "^6.21.3",
"react": "^18.3 || >=19.0.0-rc"

@@ -120,6 +120,6 @@ },

"build": "pkg build --strict --check --clean",
"dev": "pkg build --strict",
"lint": "eslint .",
"test": "vitest --pass-with-no-tests --typecheck",
"watch": "pkg watch --strict"
"test": "vitest --pass-with-no-tests --typecheck"
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc