@symbo.ls/sync 3.14.0 → 3.14.2

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/CHANGELOG.md ADDED
@@ -0,0 +1,12 @@
1
+ # @symbo.ls/sync
2
+
3
+ ## 3.14.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Auto-generated patch release for changed packages.
8
+ - Updated dependencies
9
+ - @symbo.ls/default-config@3.14.2
10
+ - @symbo.ls/scratch@3.14.2
11
+ - @symbo.ls/utils@3.14.2
12
+ - @symbo.ls/router@3.14.1
@@ -0,0 +1 @@
1
+ "use strict";var c=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var a=Object.getOwnPropertyNames;var s=Object.prototype.hasOwnProperty;var l=(t,e)=>{for(var n in e)c(t,n,{get:e[n],enumerable:!0})},f=(t,e,n,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of a(e))!s.call(t,i)&&i!==n&&c(t,i,{get:()=>e[i],enumerable:!(o=d(e,i))||o.enumerable});return t};var r=t=>f(c({},"__esModule",{value:!0}),t);var x={};l(x,{Notifications:()=>m,connectedToSymbols:()=>p});module.exports=r(x);const u={success:"green",error:"red",warning:"yellow"},p=(t,e,n)=>{if(t.symbols){if(!n.connected){n.notifications.connected={title:"Connected",message:"to the Symbols live server"},n.update({connected:!0});const o=setTimeout(()=>{delete n.notifications.connected,e.notifications.content.connected.update({animation:"fadeOutDown"}),n.update({connected:!0}),clearTimeout(o)},3e3)}}else if(n.connected){n.notifications.connected={title:"Disconnected",type:"error"},n.update({connected:!1});const o=setTimeout(()=>{delete n.notifications.connected,e.notifications.content.connected&&e.notifications.content.connected.update({animation:"fadeOutDown"}),n.update({connected:!0}),clearTimeout(o)},3e3)}},m={state:{notifications:[]},Notifications:{position:"fixed",left:"A2",bottom:"Z2",zIndex:"999",childExtends:"Notification",childProps:({state:t})=>({animationDuration:"C",background:u[t.type||"success"],icon:null,Flex:{Title:{text:"{{ title }}"},P:{text:"{{ title }}"}},onRender:(e,n,o)=>{n.update({animation:"fadeInUp"})},onClick:(e,n,o)=>{delete o.notifications[n.key],n.update({animation:"fadeOutDown"}),o.onClose&&o.onClose(e,n,o)}}),IconText:null,childrenAs:"state",children:({state:t})=>t.notifications}};
@@ -0,0 +1 @@
1
+ var s=Object.defineProperty;var y=Object.getOwnPropertyDescriptor;var h=Object.getOwnPropertyNames;var A=Object.prototype.hasOwnProperty;var g=(r,e)=>{for(var n in e)s(r,n,{get:e[n],enumerable:!0})},x=(r,e,n,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of h(e))!A.call(r,t)&&t!==n&&s(r,t,{get:()=>e[t],enumerable:!(o=y(e,t))||o.enumerable});return r};var S=r=>x(s({},"__esModule",{value:!0}),r);var k={};g(k,{FORBIDDEN_SEGMENTS:()=>f,applyOpsToCtx:()=>_,deletePath:()=>a,isSafePath:()=>u,setPath:()=>l});module.exports=S(k);const f=new Set(["__proto__","constructor","prototype"]),u=r=>{if(!Array.isArray(r))return!1;for(let e=0;e<r.length;e++)if(f.has(r[e]))return!1;return!0},a=(r,e)=>{!r||!u(e)||e.reduce((n,o,t,i)=>{if(n&&o in n){if(t!==i.length-1)return n[o];delete n[o]}},r)},l=(r,e,n,o=!1)=>{!r||!u(e)||e.reduce((t,i,d,p)=>{if(t){if(d!==p.length-1)return!t[i]&&o&&(t[i]={}),t[i];t[i]=n}},r)},_=(r,e)=>{const n=new Set;if(!Array.isArray(e))return n;for(const[o,t,i]of e)if(!(!Array.isArray(t)||!t.length))switch(n.add(t[0]),o){case"delete":a(r,t);break;case"update":case"set":l(r,t,i,!0);break;default:break}return n};
@@ -0,0 +1 @@
1
+ var p=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var d=Object.prototype.hasOwnProperty;var y=(t,o)=>{for(var e in o)p(t,e,{get:o[e],enumerable:!0})},u=(t,o,e,n)=>{if(o&&typeof o=="object"||typeof o=="function")for(let s of g(o))!d.call(t,s)&&s!==e&&p(t,s,{get:()=>o[s],enumerable:!(n=l(o,s))||n.enumerable});return t};var A=t=>u(p({},"__esModule",{value:!0}),t);var O={};y(O,{onOps:()=>w,onSnapshot:()=>S});module.exports=A(O);var f=require("smbls/src/init.js"),c=require("@symbo.ls/utils"),h=require("./applier.js");const S=(t,o,e)=>(n={})=>{let{data:s}=n;const{schema:i}=n;s&&(s=t.call("deepDestringifyFunctions",s,Array.isArray(s)?[]:{}),Object.entries(s).forEach(([r,a])=>{e[r]&&typeof e[r]=="object"?r==="designSystem"?(0,f.init)(a):(0,c.overwriteShallow)(e[r],a):e[r]=a}),i&&(e.schema=i))},w=(t,o,e)=>(n={})=>{let{changes:s}=n;if(!s||!Array.isArray(s)||!s.length)return;s=t.call("deepDestringifyFunctions",s,Array.isArray(s)?[]:{});const i=(0,h.applyOpsToCtx)(e,s);if(i.has("state")&&o.update(e.state),["pages","components","snippets","functions","assets"].some(r=>i.has(r))){const{pathname:r,search:a,hash:m}=e.window.location;t.call("router",r+a+m,t.__ref.root,{},{scrollToTop:!1})}i.has("designSystem")&&(0,f.init)(e.designSystem)};
@@ -0,0 +1 @@
1
+ var d=Object.defineProperty;var w=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var U=Object.prototype.hasOwnProperty;var T=(e,n)=>{for(var o in n)d(e,o,{get:n[o],enumerable:!0})},E=(e,n,o,t)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of g(n))!U.call(e,r)&&r!==o&&d(e,r,{get:()=>n[r],enumerable:!(t=w(n,r))||t.enumerable});return e};var A=e=>E(d({},"__esModule",{value:!0}),e);var R={};T(R,{DefaultSyncApp:()=>O,FORBIDDEN_SEGMENTS:()=>s.FORBIDDEN_SEGMENTS,Notifications:()=>c.Notifications,SyncComponent:()=>u,applyOpsToCtx:()=>s.applyOpsToCtx,connectToSocket:()=>v,deletePath:()=>s.deletePath,isSafePath:()=>s.isSafePath,notificationsPlugin:()=>M,onOps:()=>i.onOps,onSnapshot:()=>i.onSnapshot,setPath:()=>s.setPath,syncPlugin:()=>B});module.exports=A(R);var G=require("@symbo.ls/router"),f=require("socket.io-client"),l=require("@symbo.ls/utils"),s=require("./applier.js"),i=require("./handlers.js"),c=require("./SyncNotifications.js");const C=!1,D=()=>C?"http://localhost:8080":"https://api.symbols.app",I=e=>{const n=e&&e.editor&&e.editor.socketUrl||e&&e.settings&&e.settings.socketUrl;return typeof n=="string"&&n?{mode:"collab",baseUrl:n}:e&&e.editor&&e.editor.runtime==="runner"?{mode:"runner",baseUrl:null}:{mode:null,baseUrl:null}},j=async e=>{try{const n=e||D(),o=await l.window.fetch(`${n}/service-token`,{method:"GET"});let t;try{const r=await o.clone().json();if(r&&typeof r.token=="string")return r.token.trim();t=await o.text()}catch{t=await o.text()}return(t||"").replace(/\s+/gu,"")||void 0}catch(n){console.error("[sync] Failed to fetch service-token",n)}},y=(e,n,o,t)=>{e.on("snapshot",(0,i.onSnapshot)(n,o,t)),e.on("ops",(0,i.onOps)(n,o,t)),e.on("clients",r=>{t.editor?.verbose&&(0,c.connectedToSymbols)(r,n,o)}),e.on("disconnect",r=>{t.editor?.verbose&&console.info("[sync] disconnected",r)})},N=async(e,n,o,t)=>{const r=await j(t);if(!r)return console.warn("[sync] no service token \u2014 collab disabled"),null;const p=o.key;if(!p)return console.warn("[sync] ctx.key missing \u2014 collab cannot authenticate"),null;const S=o.editor?.projectId||null,a=(0,f.io)(t,{path:"/collab-socket",transports:["websocket"],auth:{token:r,projectId:S,projectKey:p,branch:"main",live:!0,clientType:"platform"},reconnectionAttempts:1/0,reconnectionDelayMax:4e3});return a.on("connect",()=>{o.editor?.verbose&&console.info("[sync] connected (collab)")}),y(a,e,n,o),a},P=(e,n,o)=>{const t=(0,f.io)({transports:["websocket","polling"],reconnectionAttempts:1/0,reconnectionDelayMax:4e3});return t.on("connect",()=>{o.editor?.verbose!==!1&&console.info("[sync] connected (runner)")}),y(t,e,n,o),t.on("reload",()=>{typeof l.window<"u"&&l.window.location&&l.window.location.reload()}),t},v=async(e,n,o)=>{const{mode:t,baseUrl:r}=I(o);return t?t==="collab"?N(e,n,o,r):t==="runner"?P(e,n,o):null:null},u={onInit:v},O={extends:[u,c.Notifications]},m=e=>typeof e>"u",b=e=>!!(e?.editor?.socketUrl||e?.settings?.socketUrl),h=e=>e?.editor?.runtime==="runner",k=(e,n)=>{Array.isArray(e.extends)?e.extends.push(n):e.extends?e.extends=[e.extends,n]:e.extends=[n]},B={name:"sync",beforeCreate(e,n){const o=n&&n.editor;(o&&!m(o.liveSync)?o.liveSync:b(n)||h(n))&&(b(n)&&!h(n)&&!n?.key||k(e,u))}},M={name:"notifications",beforeCreate(e,n){if(!n)return;const o=m(n.notifications)?null:n.notifications,t=n.editor&&n.editor.verbose===!0;(o===!0||o!==!1&&t)&&k(e,c.Notifications)}};
@@ -1,82 +1 @@
1
- const NOTIF_COLORS = {
2
- success: "green",
3
- error: "red",
4
- warning: "yellow"
5
- };
6
- const connectedToSymbols = (clients, element, state) => {
7
- if (clients.symbols) {
8
- if (!state.connected) {
9
- state.notifications.connected = {
10
- title: "Connected",
11
- message: "to the Symbols live server"
12
- };
13
- state.update({ connected: true });
14
- const t = setTimeout(() => {
15
- delete state.notifications.connected;
16
- element.notifications.content.connected.update({
17
- animation: "fadeOutDown"
18
- });
19
- state.update({ connected: true });
20
- clearTimeout(t);
21
- }, 3e3);
22
- }
23
- } else {
24
- if (state.connected) {
25
- state.notifications.connected = {
26
- title: "Disconnected",
27
- type: "error"
28
- };
29
- state.update({ connected: false });
30
- const t = setTimeout(() => {
31
- delete state.notifications.connected;
32
- if (element.notifications.content.connected) {
33
- element.notifications.content.connected.update({
34
- animation: "fadeOutDown"
35
- });
36
- }
37
- state.update({ connected: true });
38
- clearTimeout(t);
39
- }, 3e3);
40
- }
41
- }
42
- };
43
- const Notifications = {
44
- state: {
45
- notifications: []
46
- },
47
- Notifications: {
48
- position: "fixed",
49
- left: "A2",
50
- bottom: "Z2",
51
- zIndex: "999",
52
- childExtends: "Notification",
53
- childProps: ({ state }) => ({
54
- animationDuration: "C",
55
- background: NOTIF_COLORS[state.type || "success"],
56
- icon: null,
57
- Flex: {
58
- Title: {
59
- text: "{{ title }}"
60
- },
61
- P: {
62
- text: "{{ title }}"
63
- }
64
- },
65
- onRender: (e, el, s) => {
66
- el.update({ animation: "fadeInUp" });
67
- },
68
- onClick: (e, el, s) => {
69
- delete s.notifications[el.key];
70
- el.update({ animation: "fadeOutDown" });
71
- if (s.onClose) s.onClose(e, el, s);
72
- }
73
- }),
74
- IconText: null,
75
- childrenAs: "state",
76
- children: ({ state }) => state.notifications
77
- }
78
- };
79
- export {
80
- Notifications,
81
- connectedToSymbols
82
- };
1
+ const i={success:"green",error:"red",warning:"yellow"},c=(o,t,n)=>{if(o.symbols){if(!n.connected){n.notifications.connected={title:"Connected",message:"to the Symbols live server"},n.update({connected:!0});const e=setTimeout(()=>{delete n.notifications.connected,t.notifications.content.connected.update({animation:"fadeOutDown"}),n.update({connected:!0}),clearTimeout(e)},3e3)}}else if(n.connected){n.notifications.connected={title:"Disconnected",type:"error"},n.update({connected:!1});const e=setTimeout(()=>{delete n.notifications.connected,t.notifications.content.connected&&t.notifications.content.connected.update({animation:"fadeOutDown"}),n.update({connected:!0}),clearTimeout(e)},3e3)}},d={state:{notifications:[]},Notifications:{position:"fixed",left:"A2",bottom:"Z2",zIndex:"999",childExtends:"Notification",childProps:({state:o})=>({animationDuration:"C",background:i[o.type||"success"],icon:null,Flex:{Title:{text:"{{ title }}"},P:{text:"{{ title }}"}},onRender:(t,n,e)=>{n.update({animation:"fadeInUp"})},onClick:(t,n,e)=>{delete e.notifications[n.key],n.update({animation:"fadeOutDown"}),e.onClose&&e.onClose(t,n,e)}}),IconText:null,childrenAs:"state",children:({state:o})=>o.notifications}};export{d as Notifications,c as connectedToSymbols};
@@ -0,0 +1 @@
1
+ const a=new Set(["__proto__","constructor","prototype"]),s=r=>{if(!Array.isArray(r))return!1;for(let t=0;t<r.length;t++)if(a.has(r[t]))return!1;return!0},l=(r,t)=>{!r||!s(t)||t.reduce((n,i,e,o)=>{if(n&&i in n){if(e!==o.length-1)return n[i];delete n[i]}},r)},d=(r,t,n,i=!1)=>{!r||!s(t)||t.reduce((e,o,u,f)=>{if(e){if(u!==f.length-1)return!e[o]&&i&&(e[o]={}),e[o];e[o]=n}},r)},p=(r,t)=>{const n=new Set;if(!Array.isArray(t))return n;for(const[i,e,o]of t)if(!(!Array.isArray(e)||!e.length))switch(n.add(e[0]),i){case"delete":l(r,e);break;case"update":case"set":d(r,e,o,!0);break;default:break}return n};export{a as FORBIDDEN_SEGMENTS,p as applyOpsToCtx,l as deletePath,s as isSafePath,d as setPath};
@@ -0,0 +1 @@
1
+ import{init as p}from"smbls/src/init.js";import{overwriteShallow as c}from"@symbo.ls/utils";import{applyOpsToCtx as h}from"./applier.js";const d=(r,a,e)=>(i={})=>{let{data:s}=i;const{schema:o}=i;s&&(s=r.call("deepDestringifyFunctions",s,Array.isArray(s)?[]:{}),Object.entries(s).forEach(([t,n])=>{e[t]&&typeof e[t]=="object"?t==="designSystem"?p(n):c(e[t],n):e[t]=n}),o&&(e.schema=o))},y=(r,a,e)=>(i={})=>{let{changes:s}=i;if(!s||!Array.isArray(s)||!s.length)return;s=r.call("deepDestringifyFunctions",s,Array.isArray(s)?[]:{});const o=h(e,s);if(o.has("state")&&a.update(e.state),["pages","components","snippets","functions","assets"].some(t=>o.has(t))){const{pathname:t,search:n,hash:f}=e.window.location;r.call("router",t+n+f,r.__ref.root,{},{scrollToTop:!1})}o.has("designSystem")&&p(e.designSystem)};export{y as onOps,d as onSnapshot};
package/dist/esm/index.js CHANGED
@@ -1,210 +1 @@
1
- import { router } from "@symbo.ls/router";
2
- import { init } from "smbls/src/init.js";
3
- import { io } from "socket.io-client";
4
- import { window, overwriteShallow, overwriteDeep } from "@symbo.ls/utils";
5
- import { connectedToSymbols, Notifications } from "./SyncNotifications";
6
- import { Inspect } from "./Inspect";
7
- const isLocal = process.env.NODE_ENV === "local";
8
- const deletePath = (obj, path) => {
9
- if (!obj || !Array.isArray(path)) {
10
- return;
11
- }
12
- path.reduce((acc, v, i, arr) => {
13
- if (acc && v in acc) {
14
- if (i !== arr.length - 1) {
15
- return acc[v];
16
- }
17
- delete acc[v];
18
- }
19
- return void 0;
20
- }, obj);
21
- };
22
- const setPath = (obj, path, value, createNestedObjects = false) => {
23
- if (!obj || !Array.isArray(path)) {
24
- return;
25
- }
26
- path.reduce((acc, v, i, arr) => {
27
- if (!acc) {
28
- return void 0;
29
- }
30
- if (i !== arr.length - 1) {
31
- if (!acc[v] && createNestedObjects) {
32
- acc[v] = {};
33
- }
34
- return acc[v];
35
- }
36
- acc[v] = value;
37
- return void 0;
38
- }, obj);
39
- };
40
- const applyOpsToCtx = (ctx, changes) => {
41
- const topLevelChanged = /* @__PURE__ */ new Set();
42
- if (!Array.isArray(changes)) {
43
- return topLevelChanged;
44
- }
45
- for (const [action, path, change] of changes) {
46
- if (!Array.isArray(path) || !path.length) {
47
- continue;
48
- }
49
- topLevelChanged.add(path[0]);
50
- switch (action) {
51
- case "delete":
52
- deletePath(ctx, path);
53
- break;
54
- case "update":
55
- case "set":
56
- setPath(ctx, path, change, true);
57
- break;
58
- default:
59
- break;
60
- }
61
- }
62
- return topLevelChanged;
63
- };
64
- const fetchServiceToken = async () => {
65
- try {
66
- const urlBase = isLocal ? "http://localhost:8080" : "https://api.symbols.app";
67
- const res = await window.fetch(`${urlBase}/service-token`, {
68
- method: "GET"
69
- });
70
- let txt;
71
- try {
72
- const json = await res.clone().json();
73
- if (json && typeof json.token === "string") {
74
- return json.token.trim();
75
- }
76
- txt = await res.text();
77
- } catch {
78
- txt = await res.text();
79
- }
80
- return (txt || "").replace(/\s+/gu, "") || void 0;
81
- } catch (e) {
82
- console.error("[sync] Failed to fetch service-token", e);
83
- }
84
- };
85
- const onSnapshot = (el, s, ctx) => (payload = {}) => {
86
- let { data } = payload;
87
- const { schema } = payload;
88
- if (!data) {
89
- return;
90
- }
91
- data = el.call(
92
- "deepDestringifyFunctions",
93
- data,
94
- Array.isArray(data) ? [] : {}
95
- );
96
- Object.entries(data).forEach(([key, val]) => {
97
- if (ctx[key] && typeof ctx[key] === "object") {
98
- if (key === "designSystem") {
99
- init(val);
100
- } else {
101
- overwriteShallow(ctx[key], val);
102
- }
103
- } else {
104
- ctx[key] = val;
105
- }
106
- });
107
- if (schema) {
108
- ctx.schema = schema;
109
- }
110
- };
111
- const onOps = (el, s, ctx) => (payload = {}) => {
112
- let { changes } = payload;
113
- if (!changes || !Array.isArray(changes) || !changes.length) {
114
- return;
115
- }
116
- changes = el.call(
117
- "deepDestringifyFunctions",
118
- changes,
119
- Array.isArray(changes) ? [] : {}
120
- );
121
- const changed = applyOpsToCtx(ctx, changes);
122
- if (changed.has("state")) {
123
- const route = ctx.state?.route;
124
- if (route) {
125
- el.call(
126
- "router",
127
- route.replace("/state", "") || "/",
128
- el.__ref.root,
129
- {},
130
- { scrollToTop: false }
131
- );
132
- } else {
133
- s.update(ctx.state);
134
- }
135
- }
136
- if (["pages", "components", "snippets", "functions"].some(
137
- (k) => changed.has(k)
138
- )) {
139
- const { pathname, search, hash } = ctx.window.location;
140
- el.call(
141
- "router",
142
- pathname + search + hash,
143
- el.__ref.root,
144
- {},
145
- { scrollToTop: false }
146
- );
147
- }
148
- if (changed.has("designSystem")) {
149
- init(ctx.designSystem);
150
- }
151
- };
152
- const connectToSocket = async (el, s, ctx) => {
153
- const token = await fetchServiceToken();
154
- if (!token) {
155
- console.warn("[sync] No service token \u2013 live collaboration disabled");
156
- return null;
157
- }
158
- const projectKey = ctx.key;
159
- if (!projectKey) {
160
- console.warn(
161
- "[sync] ctx.key missing \u2013 cannot establish collaborative connection"
162
- );
163
- return null;
164
- }
165
- const socketBaseUrl = isLocal ? "http://localhost:8080" : "https://api.symbols.app";
166
- const socket = io(socketBaseUrl, {
167
- path: "/collab-socket",
168
- transports: ["websocket"],
169
- auth: {
170
- token,
171
- projectKey,
172
- branch: "main",
173
- live: true,
174
- clientType: "platform"
175
- },
176
- reconnectionAttempts: Infinity,
177
- reconnectionDelayMax: 4e3
178
- });
179
- socket.on("connect", () => {
180
- if (ctx.editor?.verbose) {
181
- console.info("[sync] Connected to collab socket");
182
- }
183
- });
184
- socket.on("snapshot", onSnapshot(el, s, ctx));
185
- socket.on("ops", onOps(el, s, ctx));
186
- socket.on("clients", (data) => {
187
- if (ctx.editor?.verbose) {
188
- connectedToSymbols(data, el, s);
189
- }
190
- });
191
- socket.on("disconnect", (reason) => {
192
- if (ctx.editor?.verbose) {
193
- console.info("[sync] Disconnected from collab socket", reason);
194
- }
195
- });
196
- return socket;
197
- };
198
- const SyncComponent = {
199
- onInitSync: connectToSocket
200
- };
201
- const DefaultSyncApp = {
202
- extends: [SyncComponent, Inspect, Notifications]
203
- };
204
- export {
205
- DefaultSyncApp,
206
- Inspect,
207
- Notifications,
208
- SyncComponent,
209
- connectToSocket
210
- };
1
+ import"@symbo.ls/router";import{io as a}from"socket.io-client";import{window as s}from"@symbo.ls/utils";import{FORBIDDEN_SEGMENTS as v,isSafePath as S,deletePath as w,setPath as g,applyOpsToCtx as U}from"./applier.js";import{onSnapshot as d,onOps as f}from"./handlers.js";import{connectedToSymbols as T,Notifications as c}from"./SyncNotifications.js";const E=!1,A=()=>E?"http://localhost:8080":"https://api.symbols.app",C=e=>{const n=e&&e.editor&&e.editor.socketUrl||e&&e.settings&&e.settings.socketUrl;return typeof n=="string"&&n?{mode:"collab",baseUrl:n}:e&&e.editor&&e.editor.runtime==="runner"?{mode:"runner",baseUrl:null}:{mode:null,baseUrl:null}},D=async e=>{try{const n=e||A(),o=await s.fetch(`${n}/service-token`,{method:"GET"});let t;try{const r=await o.clone().json();if(r&&typeof r.token=="string")return r.token.trim();t=await o.text()}catch{t=await o.text()}return(t||"").replace(/\s+/gu,"")||void 0}catch(n){console.error("[sync] Failed to fetch service-token",n)}},u=(e,n,o,t)=>{e.on("snapshot",d(n,o,t)),e.on("ops",f(n,o,t)),e.on("clients",r=>{t.editor?.verbose&&T(r,n,o)}),e.on("disconnect",r=>{t.editor?.verbose&&console.info("[sync] disconnected",r)})},I=async(e,n,o,t)=>{const r=await D(t);if(!r)return console.warn("[sync] no service token \u2014 collab disabled"),null;const l=o.key;if(!l)return console.warn("[sync] ctx.key missing \u2014 collab cannot authenticate"),null;const k=o.editor?.projectId||null,i=a(t,{path:"/collab-socket",transports:["websocket"],auth:{token:r,projectId:k,projectKey:l,branch:"main",live:!0,clientType:"platform"},reconnectionAttempts:1/0,reconnectionDelayMax:4e3});return i.on("connect",()=>{o.editor?.verbose&&console.info("[sync] connected (collab)")}),u(i,e,n,o),i},j=(e,n,o)=>{const t=a({transports:["websocket","polling"],reconnectionAttempts:1/0,reconnectionDelayMax:4e3});return t.on("connect",()=>{o.editor?.verbose!==!1&&console.info("[sync] connected (runner)")}),u(t,e,n,o),t.on("reload",()=>{typeof s<"u"&&s.location&&s.location.reload()}),t},N=async(e,n,o)=>{const{mode:t,baseUrl:r}=C(o);return t?t==="collab"?I(e,n,o,r):t==="runner"?j(e,n,o):null:null},p={onInit:N},V={extends:[p,c]},y=e=>typeof e>"u",m=e=>!!(e?.editor?.socketUrl||e?.settings?.socketUrl),b=e=>e?.editor?.runtime==="runner",h=(e,n)=>{Array.isArray(e.extends)?e.extends.push(n):e.extends?e.extends=[e.extends,n]:e.extends=[n]},_={name:"sync",beforeCreate(e,n){const o=n&&n.editor;(o&&!y(o.liveSync)?o.liveSync:m(n)||b(n))&&(m(n)&&!b(n)&&!n?.key||h(e,p))}},K={name:"notifications",beforeCreate(e,n){if(!n)return;const o=y(n.notifications)?null:n.notifications,t=n.editor&&n.editor.verbose===!0;(o===!0||o!==!1&&t)&&h(e,c)}};export{V as DefaultSyncApp,v as FORBIDDEN_SEGMENTS,c as Notifications,p as SyncComponent,U as applyOpsToCtx,N as connectToSocket,w as deletePath,S as isSafePath,K as notificationsPlugin,f as onOps,d as onSnapshot,g as setPath,_ as syncPlugin};
package/package.json CHANGED
@@ -1,45 +1,54 @@
1
1
  {
2
2
  "name": "@symbo.ls/sync",
3
- "version": "3.14.0",
4
- "main": "./index.js",
5
- "module": "./index.js",
3
+ "version": "3.14.2",
4
+ "main": "./dist/cjs/index.cjs",
5
+ "module": "./dist/esm/index.js",
6
6
  "gitHead": "9fc1b79b41cdc725ca6b24aec64920a599634681",
7
7
  "files": [
8
8
  "dist",
9
- "*.js",
10
- "dynamic.json"
9
+ "*.md",
10
+ "LICENSE"
11
11
  ],
12
12
  "repository": "https://github.com/symbo-ls/scratch",
13
13
  "type": "module",
14
14
  "license": "CC-BY-NC-4.0",
15
- "unpkg": "./dist/iife/index.js",
16
- "jsdelivr": "./dist/iife/index.js",
17
15
  "exports": {
18
- ".": "./index.js",
19
- "./client": "./client.js",
20
- "./server": "./server.js",
21
- "./package.json": "./package.json"
16
+ ".": {
17
+ "development": "./index.js",
18
+ "import": "./dist/esm/index.js",
19
+ "require": "./dist/cjs/index.cjs",
20
+ "default": "./dist/esm/index.js"
21
+ },
22
+ "./package.json": "./package.json",
23
+ "./applier": {
24
+ "development": "./applier.js",
25
+ "import": "./dist/esm/applier.js",
26
+ "require": "./dist/cjs/applier.cjs",
27
+ "default": "./dist/esm/applier.js"
28
+ },
29
+ "./handlers": {
30
+ "development": "./handlers.js",
31
+ "import": "./dist/esm/handlers.js",
32
+ "require": "./dist/cjs/handlers.cjs",
33
+ "default": "./dist/esm/handlers.js"
34
+ }
22
35
  },
23
36
  "source": "index.js",
24
37
  "publishConfig": {
25
- "access": "public"
38
+ "access": "restricted"
26
39
  },
27
40
  "scripts": {
28
- "copy:package:cjs": "cp ../../build/package-cjs.json dist/cjs/package.json",
29
- "build:esm": "NODE_ENV=$NODE_ENV esbuild *.js --target=es2020 --format=esm --outdir=dist/esm --define:process.env.NODE_ENV=process.env.NODE_ENV",
30
- "build:cjs": "NODE_ENV=$NODE_ENV esbuild *.js --target=node18 --format=cjs --outdir=dist/cjs --define:process.env.NODE_ENV=process.env.NODE_ENV",
31
- "build:iife": "NODE_ENV=$NODE_ENV esbuild index.js --bundle --target=es2020 --format=iife --global-name=SmblsSync --outfile=dist/iife/index.js --define:process.env.NODE_ENV=process.env.NODE_ENV --external:smbls --external:@symbo.ls/* --external:@symbo.ls/* --external:socket.io-client --external:socket.io --external:express --external:css-in-props",
32
- "build": "node ../../build/build.js",
33
- "prepublish": "npm run build && npm run copy:package:cjs"
41
+ "build:esm": "esbuild $(find . -type f -name \"*.js\" -not -path \"*/dist/*\" -not -path \"*/node_modules/*\" -not -path \"*/__tests__/*\" -not -path \"*/test/*\" -not -name \"*.test.js\") --target=es2020 --format=esm --outbase=. --outdir=dist/esm --minify --log-level=warning",
42
+ "build:cjs": "esbuild $(find . -type f -name \"*.js\" -not -path \"*/dist/*\" -not -path \"*/node_modules/*\" -not -path \"*/__tests__/*\" -not -path \"*/test/*\" -not -name \"*.test.js\") --target=node18 --format=cjs --outbase=. --outdir=dist/cjs --out-extension:.js=.cjs --minify --log-level=warning",
43
+ "build": "rimraf dist && npm run build:esm && npm run build:cjs",
44
+ "prepublishOnly": "npm run build"
34
45
  },
35
46
  "dependencies": {
36
- "@symbo.ls/router": "^3.14.0",
37
- "@symbo.ls/utils": "^3.14.0",
38
- "@symbo.ls/scratch": "^3.14.0",
39
- "@symbo.ls/default-config": "^3.14.0",
47
+ "@symbo.ls/router": "^3.14.1",
48
+ "@symbo.ls/utils": "^3.14.2",
49
+ "@symbo.ls/scratch": "^3.14.2",
50
+ "@symbo.ls/default-config": "^3.14.2",
40
51
  "chalk": "^5.4.1",
41
- "express": "^4.21.2",
42
- "socket.io": "^4.8.1",
43
52
  "socket.io-client": "^4.8.1"
44
53
  },
45
54
  "devDependencies": {
package/Inspect.js DELETED
@@ -1,190 +0,0 @@
1
- 'use strict'
2
-
3
- import * as smblsUI from '@symbo.ls/default-config/components'
4
- import { isObject, isString, isArray } from '@symbo.ls/utils'
5
- import { send } from './client.js'
6
-
7
- function returnStringExtend (_extends) {
8
- return isString(_extends) ? _extends : isArray(_extends) ? _extends.find(extItem => isString(extItem)) : ''
9
- }
10
-
11
- function getComponentKey (el) {
12
- if (!el) return
13
- const __componentKey = el.__ref.__componentKey
14
- const extendsStr = el.extends && returnStringExtend(el.extends)
15
- const parentChildExtendStr = el.parent && el.parent.childExtends && returnStringExtend(el.parent.childExtends)
16
- return (__componentKey || extendsStr || parentChildExtendStr || '').split('_')[0].split('.')[0].split('+')[0]
17
- }
18
-
19
- function findComponent (el) {
20
- if (!el || !el.__ref) return
21
- const { components, pages, editor } = el.context
22
- const componentKey = getComponentKey(el)
23
- if (editor && editor.onInitInspect) {
24
- const initInspectReturns = editor.onInitInspect(componentKey, el, el.state)
25
- if (!initInspectReturns) return findComponent(el.parent)
26
- }
27
- if (componentKey && (components[componentKey] || pages[componentKey])) {
28
- return el
29
- }
30
- return findComponent(el.parent)
31
- }
32
-
33
- const onInspect = (app, state, ctx) => {
34
- const windowOpts = ctx.window || window
35
- windowOpts.onkeydown = (ev) => {
36
- if (ev.altKey && ev.shiftKey) {
37
- app.state.update({ debugging: true, preventSelect: true }, {
38
- preventUpdate: true,
39
- preventContentUpdate: true,
40
- preventRecursive: true
41
- })
42
- }
43
- }
44
- windowOpts.onkeyup = (ev) => {
45
- if (app.state.preventSelect && (!ev.altKey || !ev.shiftKey)) {
46
- app.state.replace({ debugging: false, preventSelect: false }, {
47
- preventUpdate: true,
48
- preventContentUpdate: true,
49
- preventRecursive: true
50
- })
51
- app.Inspector.state.update({ area: false })
52
- }
53
- }
54
- }
55
-
56
- export const Inspect = {
57
- '.preventSelect': { userSelect: 'none' },
58
- '!preventSelect': { userSelect: 'auto' },
59
-
60
- onInspect,
61
-
62
- onMousemove: (ev, e, state) => {
63
- const el = ev.target.ref
64
- const component = findComponent(el)
65
- const focusState = e.Inspector.state
66
-
67
- if (!component || !state.debugging || !component.__ref) return focusState.update({ area: false })
68
-
69
- const componentKey = getComponentKey(component)
70
- const updateValue = (area) => {
71
- focusState.update({ area, focusKey: componentKey })
72
- }
73
-
74
- const update = () => {
75
- if (ev.altKey && ev.shiftKey) {
76
- const { x, y, width, height } = component.node.getBoundingClientRect()
77
- const area = { x, y, width, height }
78
-
79
- if (!focusState.area) return updateValue(area)
80
- if (focusState.area.x !== area.x) updateValue(area)
81
- } else if (focusState.area) {
82
- focusState.update({ area: false })
83
- }
84
- }
85
-
86
- window.requestAnimationFrame(() => {
87
- update()
88
- window.requestAnimationFrame(update)
89
- })
90
- },
91
-
92
- onMousedown: (ev, elem, state) => {
93
- if (!state.debugging) return
94
- const el = ev.target.ref
95
- const component = findComponent(el)
96
- if (!component) return
97
- const componentKey = getComponentKey(component)
98
- if (!componentKey) return
99
-
100
- const editor = el.context.editor
101
- if (editor && editor.onInspect) {
102
- return editor.onInspect(componentKey, el, el.state, { allowRouterWhileInspect: true })
103
- }
104
-
105
- const data = JSON.stringify({
106
- componentKey: `${componentKey}`
107
- })
108
- send.call(el.context.socket, 'route', data)
109
-
110
- ev.preventDefault()
111
- ev.stopPropagation()
112
- return false
113
- },
114
-
115
- Inspector: {
116
- state: {},
117
-
118
- transition: 'all, defaultBezier, X',
119
- position: 'fixed',
120
- hide: (el, s) => !(s.area && s.parent.debugging),
121
- style: {
122
- boxShadow: '0 0 10px #3686F733, 0 0 0 3px #3686F766, 0 0 100vmax 100vmax #000A',
123
- zIndex: '9999999',
124
- borderRadius: '10px',
125
- pointerEvents: 'none'
126
- },
127
-
128
- Span: {
129
- position: 'absolute',
130
- margin: 'A2 0',
131
- fontSize: 'Z',
132
- color: 'text',
133
- // color: 'blue',
134
- zIndex: '99999999',
135
- transition: 'all, defaultBezier, X',
136
- textDecoration: 'underline',
137
- fontWeight: '500',
138
- top: '100%',
139
- style: {
140
- boxShadow: '0 25px 10px 35px black',
141
- textShadow: '0 0 10px black'
142
- },
143
- text: '{{ focusKey }}'
144
- },
145
-
146
- onInit: ({ context }) => {
147
- const { components } = context
148
-
149
- if (isObject(components)) {
150
- const { Content, ...rest } = components
151
- for (const key in rest) {
152
- if (smblsUI[key]) continue
153
- if (!rest[key].__ref) rest[key].__ref = {}
154
- if (!rest[key].__ref.__componentKey) {
155
- rest[key].__ref.__componentKey = key
156
- }
157
- }
158
- }
159
- },
160
- onBeforeUpdate: (ch, el, s) => {
161
- const { area } = s
162
- const isDebugging = s.area && s.parent.debugging
163
-
164
- let style
165
- if (!isDebugging) {
166
- style = 'display: none !important'
167
- } else if (area) {
168
- const { x, y, width, height } = area
169
- // el.node.style = Object.stringify({
170
- // top: y - 6 + 'px',
171
- // left: x - 6 + 'px',
172
- // width: width + 12 + 'px',
173
- // height: height + 12 + 'px'
174
- // })
175
- style = `
176
- display: block !important;
177
- top: ${y - 6}px;
178
- left: ${x - 6}px;
179
- width: ${width + 12}px;
180
- height: ${height + 12}px;
181
- `
182
- }
183
-
184
- el.node.style = style
185
- el.Span.node.innerText = s.focusKey
186
-
187
- return false
188
- }
189
- }
190
- }