From 7f3edb535095b1c65b41ce794b1e67eb8fe43fc6 Mon Sep 17 00:00:00 2001 From: Arek Nawo Date: Fri, 30 Aug 2024 17:59:55 +0200 Subject: [PATCH] wip --- .vscode/settings.json | 1 + apps/docs/.astro/settings.json | 2 +- apps/landing-page/.astro/settings.json | 2 +- apps/web/package.json | 2 +- apps/web/public/sandbox.js | 230 +++++++---- apps/web/scripts/sandbox.ts | 24 +- .../fragments/collapsible-section.tsx | 2 +- .../lib/editor/extensions/element/node.tsx | 2 + .../src/lib/extensions/component-renderer.tsx | 169 +++++++- .../extensions/extension-view-renderer.tsx | 32 +- apps/web/src/lib/extensions/sandbox.ts | 16 +- .../dashboard/kanban/content-group-column.tsx | 55 +-- .../dashboard/kanban/content-piece-card.tsx | 13 +- apps/web/src/views/dashboard/kanban/index.tsx | 6 +- apps/web/src/views/extension/index.tsx | 41 +- .../backend/src/collections/extensions.ts | 3 +- .../routes/extensions/handlers/get-data.ts | 20 + .../src/routes/extensions/handlers/get.ts | 2 +- .../routes/extensions/handlers/update-data.ts | 25 ++ .../backend/src/routes/extensions/index.ts | 23 ++ packages/sdk/src/api/extension.ts | 8 + packages/sdk/src/extensions/index.ts | 280 ++++++++++++-- pnpm-lock.yaml | 361 +++++++++--------- 23 files changed, 903 insertions(+), 416 deletions(-) create mode 100644 packages/backend/src/routes/extensions/handlers/get-data.ts create mode 100644 packages/backend/src/routes/extensions/handlers/update-data.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index 8b647dbf..9f6a9d90 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -22,6 +22,7 @@ "totp", "unsign", "Unsubscribable", + "vals", "weaviate" ], "unocss.root": ["apps/web"], diff --git a/apps/docs/.astro/settings.json b/apps/docs/.astro/settings.json index db8e9d87..3271835e 100644 --- a/apps/docs/.astro/settings.json +++ b/apps/docs/.astro/settings.json @@ -1,5 +1,5 @@ { "_variables": { - "lastUpdateCheck": 1722930418730 + "lastUpdateCheck": 1723974048314 } } \ No newline at end of file diff --git a/apps/landing-page/.astro/settings.json b/apps/landing-page/.astro/settings.json index 8edc9546..23c84068 100644 --- a/apps/landing-page/.astro/settings.json +++ b/apps/landing-page/.astro/settings.json @@ -1,5 +1,5 @@ { "_variables": { - "lastUpdateCheck": 1722073136775 + "lastUpdateCheck": 1723187347646 } } \ No newline at end of file diff --git a/apps/web/package.json b/apps/web/package.json index d706842e..ead7a680 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -49,7 +49,7 @@ "@vrite/editor": "workspace:*", "@vrite/scripts": "workspace:*", "@vrite/sdk": "workspace:*", - "@vrite/tiptap-solid": "^1.0.2", + "@vrite/tiptap-solid": "^1.0.4", "clsx": "^2.1.0", "dayjs": "^1.11.10", "dompurify": "^3.0.8", diff --git a/apps/web/public/sandbox.js b/apps/web/public/sandbox.js index 04e0a05d..7d75c9c2 100644 --- a/apps/web/public/sandbox.js +++ b/apps/web/public/sandbox.js @@ -880,8 +880,8 @@ if (url.slice(0, 5) !== "data:" && url.slice(0, 5) !== "blob:") { if (lastEventId !== "") { var i2 = url.indexOf("?"); - requestURL = i2 === -1 ? url : url.slice(0, i2 + 1) + url.slice(i2 + 1).replace(/(?:^|&)([^=&]*)(?:=[^&]*)?/g, function(p2, paramName) { - return paramName === lastEventIdQueryParameterName ? "" : p2; + requestURL = i2 === -1 ? url : url.slice(0, i2 + 1) + url.slice(i2 + 1).replace(/(?:^|&)([^=&]*)(?:=[^&]*)?/g, function(p, paramName) { + return paramName === lastEventIdQueryParameterName ? "" : p; }); requestURL += (url.indexOf("?") === -1 ? "?" : "&") + lastEventIdQueryParameterName + "=" + encodeURIComponent(lastEventId); } @@ -956,30 +956,30 @@ var require_unfetch = __commonJS({ "../../node_modules/.pnpm/unfetch@4.2.0/node_modules/unfetch/dist/unfetch.js"(exports, module) { module.exports = function(e, n) { - return n = n || {}, new Promise(function(t, r) { - var s2 = new XMLHttpRequest(), o = [], u2 = [], i2 = {}, a2 = function() { + return n = n || {}, new Promise(function(t, r2) { + var s2 = new XMLHttpRequest(), o2 = [], u3 = [], i2 = {}, a = function() { return { ok: 2 == (s2.status / 100 | 0), statusText: s2.statusText, status: s2.status, url: s2.responseURL, text: function() { return Promise.resolve(s2.responseText); }, json: function() { return Promise.resolve(s2.responseText).then(JSON.parse); }, blob: function() { return Promise.resolve(new Blob([s2.response])); - }, clone: a2, headers: { keys: function() { - return o; + }, clone: a, headers: { keys: function() { + return o2; }, entries: function() { - return u2; + return u3; }, get: function(e2) { return i2[e2.toLowerCase()]; }, has: function(e2) { return e2.toLowerCase() in i2; } } }; }; - for (var l2 in s2.open(n.method || "get", e, true), s2.onload = function() { + for (var l3 in s2.open(n.method || "get", e, true), s2.onload = function() { s2.getAllResponseHeaders().replace(/^(.*?):[^\S\n]*([\s\S]*?)$/gm, function(e2, n2, t2) { - o.push(n2 = n2.toLowerCase()), u2.push([n2, t2]), i2[n2] = i2[n2] ? i2[n2] + "," + t2 : t2; - }), t(a2()); - }, s2.onerror = r, s2.withCredentials = "include" == n.credentials, n.headers) - s2.setRequestHeader(l2, n.headers[l2]); + o2.push(n2 = n2.toLowerCase()), u3.push([n2, t2]), i2[n2] = i2[n2] ? i2[n2] + "," + t2 : t2; + }), t(a()); + }, s2.onerror = r2, s2.withCredentials = "include" == n.credentials, n.headers) + s2.setRequestHeader(l3, n.headers[l3]); s2.send(n.body || null); }); }; @@ -998,83 +998,83 @@ __export(api_exports, { createClient: () => V }); - var import_eventsource, l, S, g, L, I, P, O, E, x, D, C, T, j, R, v, m, q, k, A, z, w, B, b, M, h, J, u, N, V; + var import_eventsource, l2, S, g2, L, D, k, I, E, O, x, C, T, j, R, v, m, q, w2, A, z, b2, B, y2, M, G, J, u2, N, V; var init_api = __esm({ "../../packages/sdk/dist/api.mjs"() { "use strict"; import_eventsource = __toESM(require_browser(), 1); - l = "/content-groups"; - S = (t) => ({ get: (e) => t("GET", `${l}`, { params: e }), list: (e) => t("GET", `${l}/list`, { params: e }), create: (e) => t("POST", `${l}`, { body: e }), update: (e) => t("PUT", `${l}`, { body: e }), delete: (e) => t("DELETE", `${l}`, { params: e }) }); - g = "/content-pieces"; - L = (t) => ({ get: (e) => t("GET", `${g}`, { params: e }), create: (e) => t("POST", `${g}`, { body: e }), update: (e) => t("PUT", `${g}`, { body: e }), delete: (e) => t("DELETE", `${g}`, { params: e }), list: ({ contentGroupId: e, ...o }) => t("GET", `${g}/list`, { params: { ...o, ...e && { contentGroupId: typeof e == "string" ? e : e.join(",") } } }) }); - I = (t) => { - let e = t.baseURL || "https://api.vrite.io", o = t.extensionId || "", i2 = t.headers || {}, d2 = null, { token: $ } = t; - return { sendRequest: async (s2, a2, c) => { + l2 = "/content-groups"; + S = (t) => ({ get: (e) => t("GET", `${l2}`, { params: e }), list: (e) => t("GET", `${l2}/list`, { params: e }), create: (e) => t("POST", `${l2}`, { body: e }), update: (e) => t("PUT", `${l2}`, { body: e }), delete: (e) => t("DELETE", `${l2}`, { params: e }) }); + g2 = "/content-pieces"; + L = (t) => ({ get: (e) => t("GET", `${g2}`, { params: e }), create: (e) => t("POST", `${g2}`, { body: e }), update: (e) => t("PUT", `${g2}`, { body: e }), delete: (e) => t("DELETE", `${g2}`, { params: e }), list: ({ contentGroupId: e, ...o2 }) => t("GET", `${g2}/list`, { params: { ...o2, ...e && { contentGroupId: typeof e == "string" ? e : e.join(",") } } }) }); + D = (t) => { + let e = t.baseURL || "https://api.vrite.io", o2 = t.extensionId || "", i2 = t.headers || {}, $ = null, { token: d2 } = t; + return { sendRequest: async (s2, a, c) => { try { - const { default: p2 } = await Promise.resolve().then(() => __toESM(require_browser2(), 1)), n = await p2(`${e}${a2}/?${encodeURI(Object.entries(c?.params || {}).filter(([, y]) => y).map(([y, U]) => `${y}=${U}`).join("&"))}`, { headers: { Authorization: `Bearer ${$}`, Accept: "application/json", ...c?.body ? { "Content-Type": "application/json" } : {}, ...o ? { "X-Vrite-Extension-ID": o } : {}, ...i2 }, body: c?.body ? JSON.stringify(c.body) : null, signal: d2, method: s2 }); - d2 = null; - let r = null; + const { default: p } = await Promise.resolve().then(() => __toESM(require_browser2(), 1)), n = await p(`${e}${a}/?${encodeURI(Object.entries(c?.params || {}).filter(([, h]) => h).map(([h, U]) => `${h}=${U}`).join("&"))}`, { headers: { Authorization: `Bearer ${d2}`, Accept: "application/json", ...c?.body ? { "Content-Type": "application/json" } : {}, ...o2 ? { "X-Vrite-Extension-ID": o2 } : {}, ...i2 }, body: c?.body ? JSON.stringify(c.body) : null, signal: $, method: s2 }); + $ = null; + let r2 = null; try { - if (r = await n.json(), !r) + if (r2 = await n.json(), !r2) return; } catch { return; } if (!n.ok) - throw r; - const G = n.headers.get("x-pagination-total"); - return G ? Object.assign(r, { meta: { pagination: { total: parseInt(G), pages: parseInt(n.headers.get("x-pagination-pages") || "0"), perPage: parseInt(n.headers.get("x-pagination-per-page") || "0"), page: parseInt(n.headers.get("x-pagination-page") || "0") } } }) : r; - } catch (p2) { - throw console.error(p2), p2; + throw r2; + const P = n.headers.get("x-pagination-total"); + return P ? Object.assign(r2, { meta: { pagination: { total: parseInt(P), pages: parseInt(n.headers.get("x-pagination-pages") || "0"), perPage: parseInt(n.headers.get("x-pagination-per-page") || "0"), page: parseInt(n.headers.get("x-pagination-page") || "0") } } }) : r2; + } catch (p) { + throw console.error(p), p; } }, reconfigure: (s2) => { - e = s2.baseURL || e, $ = s2.token || $, o = s2.extensionId || o, i2 = s2.headers || i2; + e = s2.baseURL || e, d2 = s2.token || d2, o2 = s2.extensionId || o2, i2 = s2.headers || i2; }, useSignal: (s2) => { - d2 = s2; - }, getConfig: () => ({ baseURL: e, token: $, extensionId: o, headers: i2 }), getSignal: () => d2 }; + $ = s2; + }, getConfig: () => ({ baseURL: e, token: d2, extensionId: o2, headers: i2 }), getSignal: () => $ }; }; - P = "/user-settings"; - O = (t) => ({ get: () => t("GET", `${P}`), update: (e) => t("PUT", `${P}`, { body: e }) }); + k = "/user-settings"; + I = (t) => ({ get: () => t("GET", `${k}`), update: (e) => t("PUT", `${k}`, { body: e }) }); E = "/tags"; - x = (t) => ({ get: (e) => t("GET", `${E}`, { params: e }), update: (e) => t("PUT", `${E}`, { body: e }), create: (e) => t("PUT", `${E}`, { body: e }), delete: (e) => t("DELETE", `${E}`, { params: e }), list: (e) => t("GET", `${E}/list`, { params: e }) }); - D = "/profile"; - C = (t) => ({ get: () => t("GET", `${D}`) }); + O = (t) => ({ get: (e) => t("GET", `${E}`, { params: e }), update: (e) => t("PUT", `${E}`, { body: e }), create: (e) => t("PUT", `${E}`, { body: e }), delete: (e) => t("DELETE", `${E}`, { params: e }), list: (e) => t("GET", `${E}/list`, { params: e }) }); + x = "/profile"; + C = (t) => ({ get: () => t("GET", `${x}`) }); T = "/webhooks"; j = (t) => ({ get: (e) => t("GET", `${T}`, { params: e }), create: (e) => t("POST", `${T}`, { body: e }), update: (e) => t("PUT", `${T}`, { body: e }), delete: (e) => t("DELETE", `${T}`, { params: e }), list: (e) => t("GET", `${T}/list`, { params: e }) }); R = "/workspace"; v = (t) => ({ get: () => t("GET", `${R}`) }); m = "/roles"; q = (t) => ({ get: (e) => t("GET", `${m}`, { params: e }), create: (e) => t("POST", `${m}`, { body: e }), update: (e) => t("PUT", `${m}`, { body: e }), delete: (e) => t("DELETE", `${m}`, { params: e }), list: (e) => t("GET", `${m}/list`, { params: e }) }); - k = "/workspace-settings"; - A = (t) => ({ get: () => t("GET", `${k}`), update: (e) => t("PUT", `${k}`, { body: e }) }); + w2 = "/workspace-settings"; + A = (t) => ({ get: () => t("GET", `${w2}`), update: (e) => t("PUT", `${w2}`, { body: e }) }); z = (t) => ({ listMembers: (e) => t("GET", "/workspace-memberships/list-members", { params: e }), listWorkspaces: (e) => t("GET", "/workspace-memberships/list-workspaces", { params: e }), create: (e) => t("POST", "/workspace-memberships", { body: e }), update: (e) => t("PUT", "/workspace-memberships", { body: e }), delete: (e) => t("DELETE", "/workspace-memberships", { params: e }) }); - w = "/extension"; - B = (t) => ({ get: () => t("GET", `${w}`), updateContentPieceData: (e) => t("POST", `${w}/content-piece-data`, { body: e }) }); - b = "/variants"; - M = (t) => ({ create: (e) => t("POST", `${b}`, { body: e }), update: (e) => t("PUT", `${b}`, { body: e }), delete: (e) => t("DELETE", `${b}`, { params: e }), list: () => t("GET", `${b}/list`) }); - h = "/transformers"; - J = (t) => ({ create: (e) => t("POST", `${h}`, { body: e }), delete: (e) => t("DELETE", `${h}`, { params: e }), list: () => t("GET", `${h}/list`) }); - u = "/snippets"; - N = (t) => ({ get: (e) => t("GET", `${u}`, { params: e }), create: (e) => t("POST", `${u}`, { body: e }), update: (e) => t("PUT", `${u}`, { body: e }), delete: (e) => t("DELETE", `${u}`, { params: e }), list: (e) => t("GET", `${u}/list`, { params: e }) }); + b2 = "/extension"; + B = (t) => ({ get: () => t("GET", `${b2}`), getData: () => t("GET", `${b2}/data`), updateData: (e) => t("PUT", `${b2}/data`, { body: e }), updateContentPieceData: (e) => t("POST", `${b2}/content-piece-data`, { body: e }) }); + y2 = "/variants"; + M = (t) => ({ create: (e) => t("POST", `${y2}`, { body: e }), update: (e) => t("PUT", `${y2}`, { body: e }), delete: (e) => t("DELETE", `${y2}`, { params: e }), list: () => t("GET", `${y2}/list`) }); + G = "/transformers"; + J = (t) => ({ create: (e) => t("POST", `${G}`, { body: e }), delete: (e) => t("DELETE", `${G}`, { params: e }), list: () => t("GET", `${G}/list`) }); + u2 = "/snippets"; + N = (t) => ({ get: (e) => t("GET", `${u2}`, { params: e }), create: (e) => t("POST", `${u2}`, { body: e }), update: (e) => t("PUT", `${u2}`, { body: e }), delete: (e) => t("DELETE", `${u2}`, { params: e }), list: (e) => t("GET", `${u2}/list`, { params: e }) }); V = (t) => { - const { sendRequest: e, reconfigure: o, getConfig: i2, getSignal: d2, useSignal: $ } = I(t), s2 = { contentGroups: S(e), contentPieces: L(e), snippets: N(e), tags: x(e), profile: C(e), userSettings: O(e), webhooks: j(e), workspace: v(e), roles: q(e), workspaceSettings: A(e), workspaceMemberships: z(e), extension: B(e), variants: M(e), transformers: J(e), search(a2) { - return e("GET", "/search", { params: a2 }); - }, async ask(a2) { + const { sendRequest: e, reconfigure: o2, getConfig: i2, getSignal: $, useSignal: d2 } = D(t), s2 = { contentGroups: S(e), contentPieces: L(e), snippets: N(e), tags: O(e), profile: C(e), userSettings: I(e), webhooks: j(e), workspace: v(e), roles: q(e), workspaceSettings: A(e), workspaceMemberships: z(e), extension: B(e), variants: M(e), transformers: J(e), search(a) { + return e("GET", "/search", { params: a }); + }, async ask(a) { let c = ""; - const p2 = new import_eventsource.default(`${i2().baseURL}/search/ask?query=${encodeURIComponent(a2.query)}`, { headers: { Authorization: `Bearer ${i2().token}`, "Content-Type": "application/json", Accept: "application/json" } }); - p2.addEventListener("error", (n) => { - const r = n; - return r.message ? a2.onError?.(r.message) : (p2.close(), a2.onEnd?.(c)); - }), p2.addEventListener("message", (n) => { - const r = decodeURIComponent(n.data); - c += r, a2.onChunk?.(r, c); - }), d2()?.addEventListener("abort", () => { - p2.close(); - }), $(null); - }, useSignal(a2) { - return $(a2), s2; - }, reconfigure(a2) { - return o(a2), s2; + const p = new import_eventsource.default(`${i2().baseURL}/search/ask?query=${encodeURIComponent(a.query)}`, { headers: { Authorization: `Bearer ${i2().token}`, "Content-Type": "application/json", Accept: "application/json" } }); + p.addEventListener("error", (n) => { + const r2 = n; + return r2.message ? a.onError?.(r2.message) : (p.close(), a.onEnd?.(c)); + }), p.addEventListener("message", (n) => { + const r2 = decodeURIComponent(n.data); + c += r2, a.onChunk?.(r2, c); + }), $()?.addEventListener("abort", () => { + p.close(); + }), d2(null); + }, useSignal(a) { + return d2(a), s2; + }, reconfigure(a) { + return o2(a), s2; }, getConfig() { return i2(); } }; @@ -1084,15 +1084,80 @@ }); // ../../packages/sdk/dist/extensions.mjs - var d = Symbol("usableEnv"); - var i = Symbol("value"); - var a = Symbol("id"); - var s = Symbol("componentName"); - var p = () => `_${Math.random().toString(36).substring(2, 9)}`; - var f = new Proxy({}, { get(t, e) { - const o = () => { + var b = Symbol("usableEnv"); + var s = Symbol("value"); + var i = Symbol("id"); + var l = Symbol("componentName"); + var o = { data: {}, func: {}, views: {}, effects: [], currentScope: null }; + var d = async (...e) => { + await Promise.all(o.effects.filter((t) => t.dependencies.some((n) => e.includes(n))).map((t) => t.run())); + }; + var f = () => `_${Math.random().toString(36).substring(2, 9)}`; + var r = (e) => e && (typeof e == "object" || typeof e == "function") && i in e && s in e; + var y = new Proxy({}, { get(e, t) { + const n = () => { }; - return Object.defineProperty(o, s, { value: e }), o; + return Object.defineProperty(n, l, { value: t }), n; + } }); + function w(e) { + if (!o.data.temp) { + const a = () => o.data.temp[s]; + Object.defineProperty(a, i, { value: "temp" }), Object.defineProperty(a, s, { value: {}, writable: true }), o.data.temp = a; + } + const t = f(), n = (a) => { + const p = o.data.temp; + p[s][t] && (p[s][t][s] = a), d(`temp.${t}`); + }, c = () => o.data.temp[s][t][s]; + return Object.defineProperty(c, i, { value: `temp.${t}` }), Object.defineProperty(c, s, { value: e, writable: true }), o.data.temp[s][t] = c, o.currentScope && o.currentScope.temp.push(t), [c, n]; + } + function g(e, t, n) { + const c = f(); + o.effects.push({ [i]: c, dependencies: t.map((a) => a[i]), run: e }), o.currentScope && o.currentScope.effects.push(c), n?.initial && e(); + } + var u = Object.assign(function(e, t) { + const [n, c] = w(e()); + return g(() => { + c(e()); + }, t, { initial: true }), n; + }, { eq: (...e) => { + const t = e.filter(r); + return u(() => e.every((n) => (r(n) ? n() : n) === (r(e[0]) ? e[0]() : e[0])), t); + }, neq: (...e) => { + const t = e.filter(r); + return u(() => e.some((n) => (r(n) ? n() : n) !== (r(e[0]) ? e[0]() : e[0])), t); + }, gt: (e, t) => { + const n = [...r(e) ? [e] : [], ...r(t) ? [t] : []]; + return u(() => (r(e) ? e() : e) > (r(t) ? t() : t), n); + }, lt: (e, t) => { + const n = [...r(e) ? [e] : [], ...r(t) ? [t] : []]; + return u(() => (r(e) ? e() : e) < (r(t) ? t() : t), n); + }, and: (...e) => { + const t = e.filter(r); + return u(() => e.every((n) => r(n) ? n() : n), t); + }, or: (...e) => { + const t = e.filter(r); + return u(() => e.some((n) => r(n) ? n() : n), t); + }, not: (e) => u(() => !(r(e) ? e() : e), r(e) ? [e] : []), add: (...e) => { + const t = e.filter(r); + return u(() => e.reduce((n, c) => n + (r(c) ? c() : c), 0), t); + }, join: (...e) => { + const t = e.filter(r); + return u(() => e.reduce((n, c) => n + (r(c) ? c() : c), ""), t); + }, sub: (...e) => { + const t = e.filter(r); + return u(() => e.reduce((n, c) => n - c(), 0), t); + }, mul: (...e) => { + const t = e.filter(r); + return u(() => e.reduce((n, c) => n * c(), 1), t); + }, div: (e, t) => { + const n = [...r(e) ? [e] : [], ...r(t) ? [t] : []]; + return u(() => (r(e) ? e() : e) / (r(t) ? t() : t), n); + }, mod: (e, t) => { + const n = [...r(e) ? [e] : [], ...r(t) ? [t] : []]; + return u(() => (r(e) ? e() : e) % (r(t) ? t() : t), n); + }, neg: (e) => u(() => -(r(e) ? e() : e), r(e) ? [e] : []), when: (e, t, n) => { + const c = r(e) ? [e] : [], a = r(t) ? [t] : [], p = r(n) ? [n] : []; + return u(() => (r(e) ? e() : e) ? r(t) ? t() : t : n ? r(n) ? n() : n : null, [...c, ...a, ...p]); } }); // scripts/sandbox.ts @@ -1105,10 +1170,13 @@ let spec = null; const { createClient } = await Promise.resolve().then(() => (init_api(), api_exports)); const client = createClient({ + ...location.ancestorOrigins.item(0)?.includes("//localhost") && { + baseURL: "http://localhost:4444" + }, token, extensionId }); - const wrapInVal = (value, path) => { + const wrapInVal = (value, path, previousVal) => { const output = () => output[metadata.__value]; output[metadata.__id] = `${path}`; if (typeof value === "object" && !Array.isArray(value) && value !== null) { @@ -1123,6 +1191,9 @@ return output; }; const unwrapVal = (value) => { + if (!r(value) && typeof value !== "function") { + return value; + } const output = value(); if (typeof output === "object" && !Array.isArray(output) && output !== null) { return Object.fromEntries( @@ -1138,7 +1209,7 @@ return; env.data = {}; Object.keys(serializedEnvData).forEach((key) => { - env.data[key] = wrapInVal(serializedEnvData[key], key); + env.data[key] = wrapInVal(serializedEnvData[key], key, env.data[key]); }); }; const serializeEnvData = () => { @@ -1211,6 +1282,7 @@ } else if (ctx.usableEnv.writable.includes(parts[1])) { const setter = (value) => { getVal()[metadata.__value] = wrapInVal(value, path)[metadata.__value]; + extension?.triggerEffects(getVal()[metadata.__id]); }; return [getter, setter]; } @@ -1241,7 +1313,7 @@ client.reconfigure({ token, extensionId }); return extension?.generateRuntimeSpec() || null; }, - generateView: async (id, envData, serializedContext, uid = p()) => { + generateView: async (id, envData, serializedContext, uid = f()) => { updateEnvData(envData); let css = ""; const view = await extension?.generateView( @@ -1259,7 +1331,7 @@ envData: serializeEnvData() }; }, - runFunction: async (id, envData, serializedContext, uid = p()) => { + runFunction: async (id, envData, serializedContext, uid = f()) => { updateEnvData(envData); await extension?.runFunction( id, @@ -1270,8 +1342,12 @@ envData: serializeEnvData() }; }, - updateEnvData: (envData) => { + updateEnvData: async (updatedIds, envData) => { updateEnvData(envData); + if (updatedIds.length && extension && "triggerEffects" in extension) { + await extension.triggerEffects(...updatedIds); + Websandbox.connection?.remote.flush(serializeEnvData()); + } return { envData: serializeEnvData() }; diff --git a/apps/web/scripts/sandbox.ts b/apps/web/scripts/sandbox.ts index 3f762ecc..df5389f9 100644 --- a/apps/web/scripts/sandbox.ts +++ b/apps/web/scripts/sandbox.ts @@ -7,7 +7,8 @@ import { ExtensionBaseViewContext, ExtensionBaseContext, Val, - generateId + generateId, + isVal } from "@vrite/sdk/extensions"; // eslint-disable-next-line init-declarations @@ -43,10 +44,13 @@ type SerializedContext = Omit< const { createClient } = await import("@vrite/sdk/api"); const client = createClient({ + ...(location.ancestorOrigins.item(0)?.includes("//localhost") && { + baseURL: "http://localhost:4444" + }), token, extensionId }); - const wrapInVal = (value: ContextValue, path: string): Val => { + const wrapInVal = (value: ContextValue, path: string, previousVal?: Val): Val => { const output = (() => output[metadata!.__value]) as Val; output[metadata!.__id] = `${path}`; @@ -64,12 +68,16 @@ type SerializedContext = Omit< return output; }; const unwrapVal = (value: Val): ContextValue => { + if (!isVal(value as Val) && typeof value !== "function") { + return value as unknown as ContextValue; + } + const output = value(); if (typeof output === "object" && !Array.isArray(output) && output !== null) { return Object.fromEntries( Object.keys(output).map((key) => { - return [key, unwrapVal(output[key] as Val)]; + return [key, unwrapVal(output[key] as Val)]; }) ); } @@ -81,7 +89,7 @@ type SerializedContext = Omit< env.data = {}; Object.keys(serializedEnvData).forEach((key) => { - env!.data[key] = wrapInVal(serializedEnvData[key], key); + env!.data[key] = wrapInVal(serializedEnvData[key], key, env!.data[key]); }); }; const serializeEnvData = (): SerializedEnvData => { @@ -169,6 +177,7 @@ type SerializedContext = Omit< } else if (ctx.usableEnv.writable.includes(parts[1])) { const setter = (value: any): void => { getVal()[metadata!.__value] = wrapInVal(value, path)[metadata!.__value]; + extension?.triggerEffects(getVal()[metadata!.__id]); }; return [getter, setter]; @@ -251,9 +260,14 @@ type SerializedContext = Omit< envData: serializeEnvData() }; }, - updateEnvData: (envData: SerializedEnvData) => { + updateEnvData: async (updatedIds: string[], envData: SerializedEnvData) => { updateEnvData(envData); + if (updatedIds.length && extension && "triggerEffects" in extension) { + await extension.triggerEffects(...updatedIds); + Websandbox.connection?.remote.flush(serializeEnvData()); + } + return { envData: serializeEnvData() }; diff --git a/apps/web/src/components/fragments/collapsible-section.tsx b/apps/web/src/components/fragments/collapsible-section.tsx index bb27533e..d2e53f01 100644 --- a/apps/web/src/components/fragments/collapsible-section.tsx +++ b/apps/web/src/components/fragments/collapsible-section.tsx @@ -1,7 +1,7 @@ import { Component, JSX, Show, createSignal } from "solid-js"; import { mdiChevronDown } from "@mdi/js"; import clsx from "clsx"; -import { Card, Heading, IconButton } from "#components/primitives"; +import { Heading, IconButton } from "#components/primitives"; interface CollapsibleSectionProps { icon: JSX.Element; diff --git a/apps/web/src/lib/editor/extensions/element/node.tsx b/apps/web/src/lib/editor/extensions/element/node.tsx index 1e74e2ca..4d217197 100644 --- a/apps/web/src/lib/editor/extensions/element/node.tsx +++ b/apps/web/src/lib/editor/extensions/element/node.tsx @@ -572,6 +572,7 @@ const Element = BaseElement.extend< newNode.type.name !== "element" ) { if (uid && customViews.has(uid)) { + customViews.get(uid)?.extension.sandbox?.removeScope(`view:${uid}`); customViews.delete(uid); } @@ -590,6 +591,7 @@ const Element = BaseElement.extend< storage.customElements[node.attrs.type.toLowerCase()] ) { if (uid && customViews.has(uid)) { + customViews.get(uid)?.extension.sandbox?.removeScope(`view:${uid}`); customViews.delete(uid); } diff --git a/apps/web/src/lib/extensions/component-renderer.tsx b/apps/web/src/lib/extensions/component-renderer.tsx index aa2a6ccf..4683f2f3 100644 --- a/apps/web/src/lib/extensions/component-renderer.tsx +++ b/apps/web/src/lib/extensions/component-renderer.tsx @@ -8,7 +8,6 @@ import { JSX, Match, on, - onMount, Show, splitProps, Switch @@ -18,9 +17,19 @@ import { createStore } from "solid-js/store"; import { ExtensionElement, ExtensionSpec, ContextObject } from "@vrite/sdk/extensions"; import { Dynamic } from "solid-js/web"; import clsx from "clsx"; -import { useNotifications } from "#context"; -import { Button, Card, Icon, IconButton, Loader, Select, Tooltip } from "#components/primitives"; -import { InputField } from "#components/fragments"; +import { mdiChevronLeft, mdiClose } from "@mdi/js"; +import { + Button, + Card, + Heading, + Icon, + IconButton, + Loader, + Select, + Tooltip +} from "#components/primitives"; +import { CollapsibleSection, InputField } from "#components/fragments"; +import { ExtensionDetails, useLocalStorage, useNotifications } from "#context"; interface ComponentRendererProps { view: ExtensionElement | string; @@ -28,12 +37,114 @@ interface ComponentRendererProps { contentEditable?: boolean; components?: Record>; } +type SidePanelHeaderSection = { + label: string; + icon: string; + id: string; + action?: ExtensionElement; +}; type RenderedComponentProps> = { contentEditable?: boolean; children: JSX.Element; + extension: ExtensionDetails; + renderView(view: ExtensionElement): JSX.Element; } & O; const baseComponents = { + SidePanelContent: (props: RenderedComponentProps) => { + return ( +
+
+
+ {props.children} +
+
+
+ ); + }, + SidePanelHeader: ( + props: RenderedComponentProps<{ + defaultSection: string; + section: string; + sections: SidePanelHeaderSection[]; + onBack?: () => void; + }> + ) => { + const getSection = (sectionId: string): SidePanelHeaderSection => { + return ( + props.sections.find(({ id }) => id === sectionId) || + props.sections[0] || { + id: "", + label: props.extension.spec.displayName, + icon: undefined + } + ); + }; + const section = (): SidePanelHeaderSection => getSection(props.section || props.defaultSection); + const defaultSection = (): SidePanelHeaderSection => getSection(props.defaultSection); + const isDefaultSection = (): boolean => props.section === props.defaultSection; + const { setStorage } = useLocalStorage(); + + return ( +
+ { + if (!isDefaultSection()) { + props.onBack?.(); + } + }} + label={defaultSection().label} + size="small" + path={mdiChevronLeft} + > +
+ + + + + + {section().label} + + + } + > + { + setStorage((storage) => ({ + ...storage, + sidePanelWidth: 0 + })); + }} + /> + + {section().label} + + + {props.renderView(section().action!)} +
+
+ ); + }, Field: (props: RenderedComponentProps>) => { return ( ) => { return {props.children}; }, + CollapsibleSection: ( + props: RenderedComponentProps<{ + icon: string; + label: string; + action?: ExtensionElement; + color?: "base" | "primary"; + defaultOpened?: boolean; + }> + ) => { + return ( + + {props.children} + + ); + }, Switch: (props: RenderedComponentProps) => { return {props.children}; }, @@ -170,11 +300,11 @@ renderer.link = (href, title, text) => { }; const ComponentRenderer: Component = (props) => { + const { notify } = useNotifications(); const components = createMemo>>(() => ({ ...baseComponents, ...props.components })); - const { notify } = useNotifications(); const { envData, setEnvData, extension } = useViewContext(); const { sandbox } = extension; @@ -190,13 +320,24 @@ const ComponentRenderer: Component = (props) => { const componentName = props.view.component.match(/^(.+?)(?:\[|\.|$)/)?.[1] || ""; const [componentProps, setComponentProps] = createStore>({}); const viewProps = props.view.props || {}; + const renderView = (view: ExtensionElement | string): JSX.Element => { + return ( + + ); + }; Object.keys(viewProps).forEach((key) => { const value = viewProps[key]; if (key.startsWith("bind:")) { const bindKey = key.slice(5); - const pathParts = `${value}`.split("."); + const path = `${value}`; + const pathParts = path.split("."); createEffect( on( @@ -218,7 +359,7 @@ const ComponentRenderer: Component = (props) => { ); setComponentProps(`set${bindKey[0].toUpperCase()}${bindKey.slice(1)}`, () => { return (value: any) => { - setEnvData((envData) => { + setEnvData([path], (envData) => { const newValue = { ...(envData as ContextObject) }; let currentObject = newValue; @@ -251,8 +392,7 @@ const ComponentRenderer: Component = (props) => { `${value}`, { contextFunctions: [], - usableEnv: { readable: [], writable: [] }, - config: {} + usableEnv: { readable: [], writable: [] } }, { notify } ); @@ -268,19 +408,14 @@ const ComponentRenderer: Component = (props) => { component={components()[componentName]} contentEditable={props.contentEditable} view={props.view} + renderView={renderView} + extension={extension} {...componentProps} > {props.view.slot?.length && ( {(view) => { - return ( - - ); + return renderView(view); }} )} diff --git a/apps/web/src/lib/extensions/extension-view-renderer.tsx b/apps/web/src/lib/extensions/extension-view-renderer.tsx index 94ebc89e..08db3226 100644 --- a/apps/web/src/lib/extensions/extension-view-renderer.tsx +++ b/apps/web/src/lib/extensions/extension-view-renderer.tsx @@ -12,7 +12,6 @@ import { on, onCleanup, onMount, - Setter, Show, useContext } from "solid-js"; @@ -33,7 +32,10 @@ type ExtensionViewRendererProps = { interface ExtensionViewContextData { extension: ExtensionDetails; envData: Accessor; - setEnvData: Setter; + setEnvData: ( + updatedIds: string[], + envData: ContextObject | ((previous: ContextObject) => ContextObject) + ) => void; } const registeredEffects = new Set(); @@ -64,8 +66,25 @@ const ExtensionViewRenderer = ( createEffect( on( () => props.usableEnvData, - (usableEnvData) => { - sandbox?.setEnvData((envData) => { + (usableEnvData, previousUsableEnvData) => { + const updatedIds = Object.keys(usableEnvData).filter((key) => { + if (!previousUsableEnvData || !(key in previousUsableEnvData)) { + return true; + } + + if ( + typeof usableEnvData[key] === "object" && + typeof previousUsableEnvData[key] === "object" + ) { + return ( + JSON.stringify(usableEnvData[key]) !== JSON.stringify(previousUsableEnvData[key]) + ); + } + + return usableEnvData[key] !== previousUsableEnvData[key]; + }); + + sandbox?.setEnvData(updatedIds, (envData) => { return { ...envData, [uid]: { @@ -123,7 +142,10 @@ const ExtensionViewRenderer = ( }); onCleanup(() => { registeredEffects.delete(uid); - sandbox?.removeScope(`view:${uid}`); + + if (viewId && !view) { + sandbox?.removeScope(`view:${uid}`); + } }); return ( diff --git a/apps/web/src/lib/extensions/sandbox.ts b/apps/web/src/lib/extensions/sandbox.ts index fbcf802e..25d24ffb 100644 --- a/apps/web/src/lib/extensions/sandbox.ts +++ b/apps/web/src/lib/extensions/sandbox.ts @@ -9,7 +9,7 @@ import { ExtensionMetadata, generateId } from "@vrite/sdk/extensions"; -import { Accessor, Setter, createEffect, createSignal, on } from "solid-js"; +import { Accessor, Setter, createSignal } from "solid-js"; import { createRef } from "#lib/utils"; import { useClient } from "#context"; @@ -59,9 +59,11 @@ type AsyncSetter = { interface ExtensionSandbox { spec: ExtensionSpec & ExtensionRuntimeSpec; envData: Accessor; - setEnvData: Setter; + setEnvData: ( + updatedIds: string[], + envData: ContextObject | ((previous: ContextObject) => ContextObject) + ) => void; setLocalEnvData: Setter; - setEnvDataAsync: AsyncSetter; destroy(): void; generateView( id: string, @@ -134,17 +136,13 @@ const loadExtensionSandbox = async ( ...runtimeSpec }, envData, - setEnvData(...args: Parameters) { + setEnvData(updatedIds, ...args: Parameters) { setEnvData(...args); - sandbox.connection?.remote.updateEnvData(JSON.parse(JSON.stringify(envData()))); + sandbox.connection?.remote.updateEnvData(updatedIds, JSON.parse(JSON.stringify(envData()))); }, setLocalEnvData(...args: Parameters) { setEnvData(...args); }, - async setEnvDataAsync(...args: Parameters) { - setEnvData(...args); - await sandbox.connection?.remote.updateEnvData(JSON.parse(JSON.stringify(envData()))); - }, destroy: () => sandbox.destroy(), generateView: async ( id: string, diff --git a/apps/web/src/views/dashboard/kanban/content-group-column.tsx b/apps/web/src/views/dashboard/kanban/content-group-column.tsx index e10b28dd..36969ca3 100644 --- a/apps/web/src/views/dashboard/kanban/content-group-column.tsx +++ b/apps/web/src/views/dashboard/kanban/content-group-column.tsx @@ -189,8 +189,8 @@ const ContentGroupColumn: Component = (props) => { data-index={props.index} {...(props.dataProps || {})} > - -
+ +
= (props) => { { contentLoader.loadContentLevel(props.contentGroup.id); }} />
= (props) => { class="min-h-[calc(100%-1rem)] flex gap-4 flex-col" ids={columnContentLevel().pieces} group="shared" - ghostClass=":base: border-2 border-gray-200 dark:border-gray-700 opacity-50 children:invisible" + ghostClass=":base: border border-gray-200 dark:border-gray-700 opacity-50 children:invisible" disabled={!hasPermission("manageDashboard")} sortableId={props.contentGroup.id} dragImage={(props) => { return ( -
+
{contentPieces[props.id]?.title}
@@ -382,50 +383,6 @@ const ContentGroupColumn: Component = (props) => {
- -
- - { - const newContentPieceData = { - contentGroupId: props.contentGroup.id, - referenceId: columnContentLevel().pieces[0], - tags: [], - members: [], - title: "" - }; - - try { - setAddingNewContentPiece(true); - - const { id } = await client.contentPieces.create.mutate(newContentPieceData); - - setAddingNewContentPiece(false); - notify({ type: "success", text: "New content piece created" }); - setStorage((storage) => ({ - ...storage, - sidePanelView: "contentPiece", - sidePanelWidth: storage.sidePanelWidth || 375 - })); - navigate(`/${id}`); - } catch (e) { - setAddingNewContentPiece(false); - notify({ type: "error", text: "Couldn't create new content piece" }); - } - }} - /> - -
); diff --git a/apps/web/src/views/dashboard/kanban/content-piece-card.tsx b/apps/web/src/views/dashboard/kanban/content-piece-card.tsx index e985e533..84061aea 100644 --- a/apps/web/src/views/dashboard/kanban/content-piece-card.tsx +++ b/apps/web/src/views/dashboard/kanban/content-piece-card.tsx @@ -51,8 +51,7 @@ const ContentPieceCard: Component = (props) => { return ( { setStorage((storage) => ({ ...storage, @@ -82,7 +81,7 @@ const ContentPieceCard: Component = (props) => {
- +
= (props) => { text={activeContentPieceId() === props.contentPiece.id ? "primary" : "soft"} color={activeContentPieceId() === props.contentPiece.id ? "primary" : "contrast"} class="whitespace-nowrap contentPiece-card-edit" + variant="text" onClick={(event) => { event.preventDefault(); event.stopPropagation(); @@ -153,7 +150,7 @@ const ContentPieceCard: Component = (props) => { }} /> - +
); }; diff --git a/apps/web/src/views/dashboard/kanban/index.tsx b/apps/web/src/views/dashboard/kanban/index.tsx index 137b9c6d..771dda7b 100644 --- a/apps/web/src/views/dashboard/kanban/index.tsx +++ b/apps/web/src/views/dashboard/kanban/index.tsx @@ -45,17 +45,17 @@ const Kanban: Component = () => { /> { return ( -
+
{contentGroups[props.id]?.name}
diff --git a/apps/web/src/views/extension/index.tsx b/apps/web/src/views/extension/index.tsx index 7f66d4cc..422fe79a 100644 --- a/apps/web/src/views/extension/index.tsx +++ b/apps/web/src/views/extension/index.tsx @@ -1,42 +1,29 @@ import { mdiClose } from "@mdi/js"; import { Component } from "solid-js"; import { Card, IconButton, Heading } from "#components/primitives"; -import { ExtensionDetails, useLocalStorage } from "#context"; +import { ExtensionDetails, useLocalStorage, useNotifications } from "#context"; +import { ExtensionViewRenderer } from "#lib/extensions"; const ExtensionSidePanelView: Component<{ extension: ExtensionDetails }> = (props) => { const { setStorage } = useLocalStorage(); + const { notify } = useNotifications(); return ( -
-
- { - setStorage((storage) => ({ - ...storage, - sidePanelWidth: 0 - })); - }} - /> - - {props.extension.spec.displayName} - -
-
-
-
-
- {/* contnet */} -
-
-
+
); }; diff --git a/packages/backend/src/collections/extensions.ts b/packages/backend/src/collections/extensions.ts index 33fcb43c..92747c28 100644 --- a/packages/backend/src/collections/extensions.ts +++ b/packages/backend/src/collections/extensions.ts @@ -23,7 +23,8 @@ const extension = z.object({ name: z.string().describe("Name of the extension"), url: z.string().describe("URL of the extension"), config: contextObject.describe("Configuration of the extension"), - token: z.string().describe("API Token of the extension") + token: z.string().describe("API Token of the extension"), + data: z.any().optional().describe("Custom data of the extension") }); interface Extension diff --git a/packages/backend/src/routes/extensions/handlers/get-data.ts b/packages/backend/src/routes/extensions/handlers/get-data.ts new file mode 100644 index 00000000..cf79cac3 --- /dev/null +++ b/packages/backend/src/routes/extensions/handlers/get-data.ts @@ -0,0 +1,20 @@ +import { z } from "zod"; +import { ObjectId } from "mongodb"; +import { getExtensionsCollection } from "#collections"; +import { Context } from "#lib/context"; + +const outputSchema = z.object({}).passthrough(); +const handler = async (ctx: Context): Promise> => { + const extensionsCollection = getExtensionsCollection(ctx.db); + const extensionId = ctx.req.headers["x-vrite-extension-id"] as string | undefined; + + if (!extensionId) return {}; + + const extension = await extensionsCollection.findOne({ + _id: new ObjectId(extensionId) + }); + + return extension?.data || {}; +}; + +export { outputSchema, handler }; diff --git a/packages/backend/src/routes/extensions/handlers/get.ts b/packages/backend/src/routes/extensions/handlers/get.ts index d737b88d..28c732c8 100644 --- a/packages/backend/src/routes/extensions/handlers/get.ts +++ b/packages/backend/src/routes/extensions/handlers/get.ts @@ -3,7 +3,7 @@ import { ObjectId } from "mongodb"; import { extension, getExtensionsCollection } from "#collections"; import { Context } from "#lib/context"; -const outputSchema = extension.partial(); +const outputSchema = extension.omit({ data: true }).partial(); const handler = async (ctx: Context): Promise> => { const extensionsCollection = getExtensionsCollection(ctx.db); const extensionId = ctx.req.headers["x-vrite-extension-id"] as string | undefined; diff --git a/packages/backend/src/routes/extensions/handlers/update-data.ts b/packages/backend/src/routes/extensions/handlers/update-data.ts new file mode 100644 index 00000000..4455908e --- /dev/null +++ b/packages/backend/src/routes/extensions/handlers/update-data.ts @@ -0,0 +1,25 @@ +import { z } from "zod"; +import { ObjectId } from "mongodb"; +import { getExtensionsCollection } from "#collections"; +import { Context } from "#lib/context"; + +const inputSchema = z.object({ + data: z.object({}).passthrough() +}); +const handler = async (ctx: Context, input: z.infer): Promise => { + const extensionsCollection = getExtensionsCollection(ctx.db); + const extensionId = ctx.req.headers["x-vrite-extension-id"] as string | undefined; + + if (!extensionId) return; + + await extensionsCollection.updateOne( + { _id: new ObjectId(extensionId) }, + { + $set: { + data: input + } + } + ); +}; + +export { inputSchema, handler }; diff --git a/packages/backend/src/routes/extensions/index.ts b/packages/backend/src/routes/extensions/index.ts index 35b06605..a846514d 100644 --- a/packages/backend/src/routes/extensions/index.ts +++ b/packages/backend/src/routes/extensions/index.ts @@ -4,6 +4,8 @@ import * as uninstallExtension from "./handlers/uninstall"; import * as updateContentPieceData from "./handlers/update-content-piece-data"; import * as listExtensions from "./handlers/list"; import * as configureExtension from "./handlers/configure"; +import * as getData from "./handlers/get-data"; +import * as updateData from "./handlers/update-data"; import { z } from "zod"; import { subscribeToExtensionEvents } from "#events/extension"; import { procedure, router } from "#lib/trpc"; @@ -19,6 +21,27 @@ const extensionsRouter = router({ .query(async ({ ctx }) => { return getExtension.handler(ctx); }), + getData: procedure + .meta({ openapi: { method: "GET", path: `${basePath}/data` }, requiredConfig: ["extensions"] }) + .input(z.void()) + .output(getData.outputSchema) + .query(async ({ ctx }) => { + return getData.handler(ctx); + }), + updateData: authenticatedProcedure + .meta({ + openapi: { + method: "PUT", + path: `${basePath}/data` + }, + requiredConfig: ["extensions"], + requiredSubscriptionPlan: "personal" + }) + .input(updateData.inputSchema) + .output(z.void()) + .mutation(async ({ ctx, input }) => { + return updateData.handler(ctx, input); + }), updateContentPieceData: authenticatedProcedure .meta({ openapi: { diff --git a/packages/sdk/src/api/extension.ts b/packages/sdk/src/api/extension.ts index 9e858f77..4f9fa9f9 100644 --- a/packages/sdk/src/api/extension.ts +++ b/packages/sdk/src/api/extension.ts @@ -16,6 +16,8 @@ interface Extension { } interface ExtensionEndpoints { get(): Promise>; + getData(): Promise; + updateData(input: { data: ContextObject }): Promise; updateContentPieceData(input: { contentPieceId: string; data: ContextObject }): Promise; } @@ -24,6 +26,12 @@ const createExtensionEndpoints = (sendRequest: SendRequest): ExtensionEndpoints get: () => { return sendRequest>("GET", `${basePath}`); }, + getData: () => { + return sendRequest("GET", `${basePath}/data`); + }, + updateData: (input) => { + return sendRequest("PUT", `${basePath}/data`, { body: input }); + }, updateContentPieceData: (input) => { return sendRequest("POST", `${basePath}/content-piece-data`, { body: input }); } diff --git a/packages/sdk/src/extensions/index.ts b/packages/sdk/src/extensions/index.ts index 1d9c5a20..bcdc8d6d 100644 --- a/packages/sdk/src/extensions/index.ts +++ b/packages/sdk/src/extensions/index.ts @@ -60,14 +60,14 @@ type UseEnv = C[typeof __usableEnv] extends Usab ? Val[K]> : K extends keyof Flatten ? [ - Val[K]>, + MutableVal[K]>, (value: Flatten[K]) => void ] : K extends keyof C[typeof __usableEnv]["readable"] ? Val : K extends keyof C[typeof __usableEnv]["writable"] ? [ - Val, + MutableVal, (value: C[typeof __usableEnv]["writable"][K]) => void ] : never @@ -115,6 +115,8 @@ interface ExtensionElementViewContext< declare const __brand: unique symbol; // eslint-disable-next-line init-declarations declare const __props: unique symbol; +// eslint-disable-next-line init-declarations +declare const __mutable: unique symbol; const __usableEnv: unique symbol = Symbol("usableEnv"); const __value: unique symbol = Symbol("value"); @@ -128,6 +130,10 @@ type Val = Val & { [__mutable]: true }; + type Func = Brand<"Func"> & { (context: C): void | Promise; [__id]: string; @@ -136,7 +142,17 @@ interface ExtensionEnvironment { data: Record; func: Record>; views: Record>; - currentScope: { func: string[]; temp: string[]; uid: string } | null; + effects: Array<{ + [__id]: string; + dependencies: string[]; + run: () => void; + }>; + currentScope: { + func: string[]; + temp: string[]; + effects: string[]; + uid: string; + } | null; } interface ExtensionMetadata { __value: typeof __value; @@ -184,6 +200,7 @@ interface ExtensionRuntimeSpec { interface Extension { getMetadata: () => ExtensionMetadata; getEnvironment: () => ExtensionEnvironment; + triggerEffects: (...dependencies: string[]) => Promise; generateRuntimeSpec: () => ExtensionRuntimeSpec; generateView: ( id: string, @@ -200,17 +217,20 @@ interface Extension { type BaseProps

> = { [K in keyof P as Exclude]?: P[K]; }; -type BindableProps

> = { - [K in keyof P as `bind:${Exclude}`]?: Val; +type BindableProps

, M extends string | never = never> = { + [K in keyof P as `bind:${Exclude, M>}`]?: Val; +} & { + [K in keyof P as `bind:${Extract, M>}`]?: MutableVal; }; type EventProps = { [K in E as `on:${Exclude}`]?: Func; }; interface ExtensionBaseComponent< P extends Record = Record, - E extends string | never = never + E extends string | never = never, + M extends string | never = never > { - (props: BaseProps

& BindableProps

& EventProps): void; + (props: BaseProps

& BindableProps & EventProps): void; [__componentName]: string; [__props]: P; } @@ -225,6 +245,20 @@ interface ExtensionBaseComponents { Element: ExtensionBaseComponent<{ type: string }>; // Layout Components View: ExtensionBaseComponent<{ class: string }>; + SidePanelHeader: ExtensionBaseComponent< + { + defaultSection: string; + section: string; + sections: Array<{ + label: string; + icon?: string; + id: string; + action?: ExtensionElement; + }>; + }, + "back" + >; + SidePanelContent: ExtensionBaseComponent<{}>; // UI Components Field: ExtensionBaseComponent< { @@ -238,7 +272,8 @@ interface ExtensionBaseComponents { optional: boolean; options?: Array<{ label: string; value: string }>; }, - "change" + "change", + "value" >; Select: ExtensionBaseComponent< { @@ -249,12 +284,14 @@ interface ExtensionBaseComponents { color?: "base" | "contrast"; wrapperClass?: string; }, - "change" + "change", + "value" >; Tooltip: ExtensionBaseComponent<{ text: string; class: string; fixed: boolean; + side?: "top" | "bottom" | "left" | "right"; }>; Button: ExtensionBaseComponent< { @@ -291,6 +328,13 @@ interface ExtensionBaseComponents { }, "click" >; + CollapsibleSection: ExtensionBaseComponent<{ + icon: string; + label: string; + action?: ExtensionElement; + color?: "base" | "primary"; + defaultOpened?: boolean; + }>; // Control Components Switch: ExtensionBaseComponent<{}>; Match: ExtensionBaseComponent<{ @@ -300,7 +344,7 @@ interface ExtensionBaseComponents { when: ContextValue; }>; Text: ExtensionBaseComponent<{ - content: string; + content: ContextValue; }>; } type ExtensionElement = { @@ -333,12 +377,34 @@ const env: ExtensionEnvironment = { data: {}, func: {}, views: {}, + effects: [], currentScope: null }; -const scopes: Record = {}; +const triggerEffects = async (...dependencies: string[]): Promise => { + await Promise.all( + env.effects + .filter((effect) => { + return effect.dependencies.some((dependency) => { + return dependencies.includes(dependency); + }); + }) + .map((effect) => { + return effect.run(); + }) + ); +}; +const scopes: Record = {}; const generateId = (): string => { return `_${Math.random().toString(36).substring(2, 9)}`; }; +const isVal = (value: T | Val): value is Val => { + return ( + value && + (typeof value === "object" || typeof value === "function") && + __id in value && + __value in value + ); +}; const Components = new Proxy({} as ExtensionBaseComponents, { get(_, key) { const component = (): void => {}; @@ -351,16 +417,16 @@ const Components = new Proxy({} as ExtensionBaseComponents, { } }); -function createTemp(initialValue: T): [Val, (value: T) => void]; +function createTemp(initialValue: T): [MutableVal, (value: T) => void]; function createTemp( initialValue?: T -): [Val, (value: T | undefined) => void]; +): [MutableVal, (value: T | undefined) => void]; function createTemp( initialValue?: T -): [Val, (value: T | undefined) => void] { +): [MutableVal, (value: T | undefined) => void] { if (!env.data.temp) { - const tempVal = (() => env.data.temp[__value]) as Val<{ - [key: string]: Val; + const tempVal = (() => env.data.temp[__value]) as MutableVal<{ + [key: string]: MutableVal; }>; Object.defineProperty(tempVal, __id, { @@ -372,29 +438,31 @@ function createTemp( const id = generateId(); const setter = (value: T | undefined): void => { - const tempVal = env.data.temp as Val<{ - [key: string]: Val; + const tempVal = env.data.temp as MutableVal<{ + [key: string]: MutableVal; }>; if (tempVal[__value][id]) { tempVal[__value][id][__value] = value; } + + triggerEffects(`temp.${id}`); }; const temp = (() => { - const tempVal = env.data.temp as Val<{ - [key: string]: Val; + const tempVal = env.data.temp as MutableVal<{ + [key: string]: MutableVal; }>; return tempVal[__value][id]![__value]; - }) as Val; + }) as MutableVal; Object.defineProperty(temp, __id, { value: `temp.${id}` }); Object.defineProperty(temp, __value, { value: initialValue, writable: true }); ( - env.data.temp as Val<{ - [key: string]: Val; + env.data.temp as MutableVal<{ + [key: string]: MutableVal; }> )[__value][id] = temp; @@ -405,6 +473,154 @@ function createTemp( return [temp, setter]; } +function effect( + run: () => void, + dependencies: D, + options?: { initial?: boolean } +): void { + const id = generateId(); + + env.effects.push({ + [__id]: id, + dependencies: dependencies.map((dep) => dep[__id]), + run + }); + + if (env.currentScope) { + env.currentScope.effects.push(id); + } + + if (options?.initial) { + run(); + } +} + +const computed = Object.assign( + function (compute: () => O, dependencies: Val[]): Val { + const [computedTemp, setComputedTemp] = createTemp(compute()); + + effect( + () => { + setComputedTemp(compute()); + }, + dependencies, + { initial: true } + ); + + return computedTemp as Val; + }, + { + eq: (...values: Array | ContextValue>): Val => { + const vals = values.filter(isVal); + + return computed(() => { + return values.every((value) => { + return (isVal(value) ? value() : value) === (isVal(values[0]) ? values[0]() : values[0]); + }); + }, vals); + }, + neq: (...values: Array | ContextValue>): Val => { + const vals = values.filter(isVal); + + return computed(() => { + return values.some((value) => { + return (isVal(value) ? value() : value) !== (isVal(values[0]) ? values[0]() : values[0]); + }); + }, vals); + }, + gt: (a: number | Val, b: number | Val): Val => { + const dependencies: Val[] = [...(isVal(a) ? [a] : []), ...(isVal(b) ? [b] : [])]; + + return computed(() => (isVal(a) ? a() : a) > (isVal(b) ? b() : b), dependencies); + }, + lt: (a: number | Val, b: number | Val): Val => { + const dependencies: Val[] = [...(isVal(a) ? [a] : []), ...(isVal(b) ? [b] : [])]; + + return computed(() => (isVal(a) ? a() : a) < (isVal(b) ? b() : b), dependencies); + }, + and: (...values: Array | ContextValue>): Val => { + const vals = values.filter(isVal); + + return computed(() => { + return values.every((value) => (isVal(value) ? value() : value)); + }, vals); + }, + or: (...values: Array | ContextValue>): Val => { + const vals = values.filter(isVal); + + return computed(() => { + return values.some((value) => (isVal(value) ? value() : value)); + }, vals); + }, + not: (value: Val | ContextValue): Val => { + return computed(() => !(isVal(value) ? value() : value), isVal(value) ? [value] : []); + }, + add: (...values: Array | number>): Val => { + const vals = values.filter(isVal); + + return computed(() => { + return values.reduce((acc, val) => acc + (isVal(val) ? val() : val), 0); + }, vals); + }, + join: (...values: Array | string>): Val => { + const vals = values.filter(isVal); + + return computed(() => { + return values.reduce((acc, val) => acc + (isVal(val) ? val() : val), ""); + }, vals); + }, + sub: (...values: Val[]): Val => { + const vals = values.filter(isVal); + + return computed(() => { + return values.reduce((acc, val) => acc - val(), 0); + }, vals); + }, + mul: (...values: Val[]): Val => { + const vals = values.filter(isVal); + + return computed(() => { + return values.reduce((acc, val) => acc * val(), 1); + }, vals); + }, + div: (a: number | Val, b: number | Val): Val => { + const dependencies: Val[] = [...(isVal(a) ? [a] : []), ...(isVal(b) ? [b] : [])]; + + return computed(() => (isVal(a) ? a() : a) / (isVal(b) ? b() : b), dependencies); + }, + mod: (a: number | Val, b: number | Val): Val => { + const dependencies: Val[] = [...(isVal(a) ? [a] : []), ...(isVal(b) ? [b] : [])]; + + return computed(() => (isVal(a) ? a() : a) % (isVal(b) ? b() : b), dependencies); + }, + neg: (value: number | Val): Val => { + return computed(() => -(isVal(value) ? value() : value), isVal(value) ? [value] : []); + }, + when: ( + condition: ContextValue | Val, + ifTrue: T | Val, + ifFalse?: F | Val + ): F extends undefined ? Val : Val => { + const dependencies: Val[] = isVal(condition) ? [condition] : []; + const trueDependencies: Val[] = isVal(ifTrue) ? [ifTrue] : []; + const falseDependencies: Val[] = isVal(ifFalse) ? [ifFalse] : []; + + return computed(() => { + if (isVal(condition) ? condition() : condition) { + return isVal(ifTrue) ? ifTrue() : ifTrue; + } + + if (ifFalse) { + return isVal(ifFalse) ? ifFalse() : ifFalse; + } + + return null; + }, [...dependencies, ...trueDependencies, ...falseDependencies]) as F extends undefined + ? Val + : Val; + } + } +); const createFunction = ( run: (context: C) => void ): Func => { @@ -471,14 +687,19 @@ const removeScope = (id: string): void => { delete env.func[funcId]; }); scope.temp.forEach((tempId) => { - const tempVal = env.data.temp as Val<{ - [key: string]: Val; + const tempVal = env.data.temp as MutableVal<{ + [key: string]: MutableVal; }>; if (tempVal()) { delete tempVal()[tempId]; } }); + scope.effects.forEach((effectId) => { + env.effects = env.effects.filter((effect) => { + return effect[__id] !== effectId; + }); + }); } }; const createRuntime = ( @@ -492,6 +713,7 @@ const createRuntime = ( __componentName, __usableEnv }), + triggerEffects, generateRuntimeSpec: () => { return { ...runtimeConfig, @@ -526,6 +748,7 @@ const createRuntime = ( env.currentScope = { func: [], temp: [], + effects: [], uid }; @@ -553,6 +776,7 @@ const createRuntime = ( env.currentScope = { func: [], temp: [], + effects: [], uid }; await runFunc(context); @@ -573,7 +797,10 @@ export { createElement, createFragment, createRuntime, - generateId + effect, + computed, + generateId, + isVal }; export type { Extension, @@ -597,5 +824,6 @@ export type { View, Func, Val, + MutableVal, Brand }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 21014bfd..7b9b0c8b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -632,8 +632,8 @@ importers: specifier: workspace:* version: link:../../packages/sdk '@vrite/tiptap-solid': - specifier: ^1.0.2 - version: 1.0.2(@tiptap/core@2.2.6)(@tiptap/pm@2.2.6)(solid-js@1.8.14) + specifier: ^1.0.4 + version: 1.0.4(@tiptap/core@2.2.6)(@tiptap/pm@2.2.6)(solid-js@1.8.14) clsx: specifier: ^2.1.0 version: 2.1.0 @@ -693,7 +693,7 @@ importers: version: 4.0.1 y-prosemirror: specifier: ^1.2.2 - version: 1.2.2(prosemirror-model@1.19.4)(prosemirror-state@1.4.3)(prosemirror-view@1.33.1)(y-protocols@1.0.6)(yjs@13.6.11) + version: 1.2.2(prosemirror-model@1.22.3)(prosemirror-state@1.4.3)(prosemirror-view@1.33.9)(y-protocols@1.0.6)(yjs@13.6.11) yjs: specifier: ^13.6.11 version: 13.6.11 @@ -763,7 +763,7 @@ importers: version: 8.3.1 '@hocuspocus/transformer': specifier: ^2.11.3 - version: 2.11.3(@tiptap/pm@2.2.6)(y-prosemirror@1.2.2)(yjs@13.6.11) + version: 2.11.3(@tiptap/pm@2.5.9)(y-prosemirror@1.2.2)(yjs@13.6.11) '@octokit/types': specifier: ^12.4.0 version: 12.4.0 @@ -772,7 +772,7 @@ importers: version: 1.7.0(typescript@5.3.3) '@tiptap/html': specifier: ^2.2.6 - version: 2.2.6(@tiptap/core@2.2.6)(@tiptap/pm@2.2.6) + version: 2.2.6(@tiptap/core@2.2.6)(@tiptap/pm@2.5.9) '@trpc/client': specifier: ^10.45.0 version: 10.45.0(@trpc/server@10.45.0) @@ -5504,17 +5504,17 @@ packages: - utf-8-validate dev: false - /@hocuspocus/transformer@2.11.3(@tiptap/pm@2.2.6)(y-prosemirror@1.2.2)(yjs@13.6.11): + /@hocuspocus/transformer@2.11.3(@tiptap/pm@2.5.9)(y-prosemirror@1.2.2)(yjs@13.6.11): resolution: {integrity: sha512-xwvweF0P1T8MjD+Dw/2nwqi0ctL9a+JO/HIYDXqcCn1OJ956jrblRfMGJhXqXUjUd17qAxeBPiPh9gjtceQNig==} peerDependencies: '@tiptap/pm': ^2.1.12 y-prosemirror: ^1.2.1 yjs: ^13.6.8 dependencies: - '@tiptap/core': 2.2.6(@tiptap/pm@2.2.6) - '@tiptap/pm': 2.2.6 - '@tiptap/starter-kit': 2.2.3(@tiptap/pm@2.2.6) - y-prosemirror: 1.2.2(prosemirror-model@1.19.4)(prosemirror-state@1.4.3)(prosemirror-view@1.33.1)(y-protocols@1.0.6)(yjs@13.6.11) + '@tiptap/core': 2.2.6(@tiptap/pm@2.5.9) + '@tiptap/pm': 2.5.9 + '@tiptap/starter-kit': 2.2.3(@tiptap/pm@2.5.9) + y-prosemirror: 1.2.2(prosemirror-model@1.22.3)(prosemirror-state@1.4.3)(prosemirror-view@1.33.9)(y-protocols@1.0.6)(yjs@13.6.11) yjs: 13.6.11 dev: false @@ -7409,30 +7409,6 @@ packages: resolution: {integrity: sha512-dyHY+sMF0ihPus3O27ODd4+agdHMEmuRdyiZJ2CCWjPV5UFmn17ZbElvk6WOGVE4rdCJKZQCrPV2BcikOMLUGQ==} dev: false - /@remirror/core-helpers@3.0.0: - resolution: {integrity: sha512-tusEgQJIqg4qKj6HSBUFcyRnWnziw3neh4T9wOmsPGHFC3w9kl5KSrDb9UAgE8uX6y32FnS7vJ955mWOl3n50A==} - dependencies: - '@remirror/core-constants': 2.0.2 - '@remirror/types': 1.0.1 - '@types/object.omit': 3.0.3 - '@types/object.pick': 1.3.4 - '@types/throttle-debounce': 2.1.0 - case-anything: 2.1.13 - dash-get: 1.0.2 - deepmerge: 4.3.1 - fast-deep-equal: 3.1.3 - make-error: 1.3.6 - object.omit: 3.0.0 - object.pick: 1.3.0 - throttle-debounce: 3.0.1 - dev: false - - /@remirror/types@1.0.1: - resolution: {integrity: sha512-VlZQxwGnt1jtQ18D6JqdIF+uFZo525WEqrfp9BOc3COPpK4+AWCgdnAWL+ho6imWcoINlGjR/+3b6y5C1vBVEA==} - dependencies: - type-fest: 2.19.0 - dev: false - /@rollup/plugin-alias@5.1.0(rollup@3.29.4): resolution: {integrity: sha512-lpA3RZ9PdIG7qqhEfv79tBffNaoDuukFDrmhLqg9ifv99u/ehn+lOg30x2zmhf8AQqQUZaMk/B9fZraQ6/acDQ==} engines: {node: '>=14.0.0'} @@ -8547,6 +8523,14 @@ packages: '@tiptap/pm': 2.2.6 dev: false + /@tiptap/core@2.2.6(@tiptap/pm@2.5.9): + resolution: {integrity: sha512-v7S7RhQhTXQo9KSk2jM/jJlTd3clU2FsJA3Omjz7GbgYtPSy67qSiaTbH/tWq12GzDHbKymx+oQnKmyx+yPucA==} + peerDependencies: + '@tiptap/pm': ^2.0.0 + dependencies: + '@tiptap/pm': 2.5.9 + dev: false + /@tiptap/extension-blockquote@2.2.6(@tiptap/core@2.2.6): resolution: {integrity: sha512-Qoq4Tl4wyEGfuBrMFth5hWP1SroJtgDYPnyzAZeLiGzF3Yxtu7FFqjGtD1/Bos9ftnFVCAj+nIXnuKsM1YUaGg==} peerDependencies: @@ -8574,11 +8558,11 @@ packages: tippy.js: 6.3.7 dev: false - /@tiptap/extension-bubble-menu@2.4.0(@tiptap/core@2.2.6)(@tiptap/pm@2.2.6): - resolution: {integrity: sha512-s99HmttUtpW3rScWq8rqk4+CGCwergNZbHLTkF6Rp6TSboMwfp+rwL5Q/JkcAG9KGLso1vGyXKbt1xHOvm8zMw==} + /@tiptap/extension-bubble-menu@2.5.9(@tiptap/core@2.2.6)(@tiptap/pm@2.2.6): + resolution: {integrity: sha512-NddZ8Qn5dgPPa1W4yk0jdhF4tDBh0FwzBpbnDu2Xz/0TUHrA36ugB2CvR5xS1we4zUKckgpVqOqgdelrmqqFVg==} peerDependencies: - '@tiptap/core': ^2.0.0 - '@tiptap/pm': ^2.0.0 + '@tiptap/core': ^2.5.9 + '@tiptap/pm': ^2.5.9 dependencies: '@tiptap/core': 2.2.6(@tiptap/pm@2.2.6) '@tiptap/pm': 2.2.6 @@ -8625,6 +8609,16 @@ packages: '@tiptap/pm': 2.2.6 dev: false + /@tiptap/extension-code-block@2.2.3(@tiptap/core@2.2.6)(@tiptap/pm@2.5.9): + resolution: {integrity: sha512-1xFM2Aj/JEWAT1PWjQ/7hEVmo1Av6JHxTANxMIjXUcmrMJkXDA+BQ7yItlwrrHxY0SJdxBbR/WWFn4dWIxd7iA==} + peerDependencies: + '@tiptap/core': ^2.0.0 + '@tiptap/pm': ^2.0.0 + dependencies: + '@tiptap/core': 2.2.6(@tiptap/pm@2.5.9) + '@tiptap/pm': 2.5.9 + dev: false + /@tiptap/extension-code@2.2.6(@tiptap/core@2.2.6): resolution: {integrity: sha512-UGsSFvVWrWWWQFU4atk+b/qeewTLadOZG/BHZXQDloyP5eJ1SkgUVy9nv3y2cT8QWRbvF6sxkV+SdFoWnvaG3Q==} peerDependencies: @@ -8640,7 +8634,7 @@ packages: y-prosemirror: ^1.2.1 dependencies: '@tiptap/core': 2.2.6(@tiptap/pm@2.2.6) - y-prosemirror: 1.2.2(prosemirror-model@1.19.4)(prosemirror-state@1.4.3)(prosemirror-view@1.33.1)(y-protocols@1.0.6)(yjs@13.6.11) + y-prosemirror: 1.2.2(prosemirror-model@1.22.3)(prosemirror-state@1.4.3)(prosemirror-view@1.33.9)(y-protocols@1.0.6)(yjs@13.6.11) dev: false /@tiptap/extension-collaboration@2.2.6(@tiptap/core@2.2.6)(@tiptap/pm@2.2.6)(y-prosemirror@1.2.2): @@ -8652,7 +8646,7 @@ packages: dependencies: '@tiptap/core': 2.2.6(@tiptap/pm@2.2.6) '@tiptap/pm': 2.2.6 - y-prosemirror: 1.2.2(prosemirror-model@1.19.4)(prosemirror-state@1.4.3)(prosemirror-view@1.33.1)(y-protocols@1.0.6)(yjs@13.6.11) + y-prosemirror: 1.2.2(prosemirror-model@1.22.3)(prosemirror-state@1.4.3)(prosemirror-view@1.33.9)(y-protocols@1.0.6)(yjs@13.6.11) dev: false /@tiptap/extension-document@2.2.6(@tiptap/core@2.2.6): @@ -8673,6 +8667,16 @@ packages: '@tiptap/pm': 2.2.6 dev: false + /@tiptap/extension-dropcursor@2.5.9(@tiptap/core@2.2.6)(@tiptap/pm@2.5.9): + resolution: {integrity: sha512-nEOb37UryG6bsU9JAs/HojE6Jg43LupNTAMISbnuB1CPAeAqNsFMwORd9eEPkyEwnQT7MkhsMOSJM44GoPGIFA==} + peerDependencies: + '@tiptap/core': ^2.5.9 + '@tiptap/pm': ^2.5.9 + dependencies: + '@tiptap/core': 2.2.6(@tiptap/pm@2.5.9) + '@tiptap/pm': 2.5.9 + dev: false + /@tiptap/extension-floating-menu@2.2.6(@tiptap/core@2.2.6)(@tiptap/pm@2.2.6): resolution: {integrity: sha512-6ONKC6Dx8zCc5YffXpnQ9FxGRoUp5Jm9mOO3losgiDFhdJqaO7SCk1ziOiD7enoWqIc2shZh8ADnqttCfnFVFQ==} peerDependencies: @@ -8684,11 +8688,11 @@ packages: tippy.js: 6.3.7 dev: false - /@tiptap/extension-floating-menu@2.4.0(@tiptap/core@2.2.6)(@tiptap/pm@2.2.6): - resolution: {integrity: sha512-vLb9v+htbHhXyty0oaXjT3VC8St4xuGSHWUB9GuAJAQ+NajIO6rBPbLUmm9qM0Eh2zico5mpSD1Qtn5FM6xYzg==} + /@tiptap/extension-floating-menu@2.5.9(@tiptap/core@2.2.6)(@tiptap/pm@2.2.6): + resolution: {integrity: sha512-MWJIQQT6e5MgqHny8neeH2Dx926nVPF7sv4p84nX4E0dnkRbEYUP8mCsWYhSUvxxIif6e+yY+4654f2Q9qTx1w==} peerDependencies: - '@tiptap/core': ^2.0.0 - '@tiptap/pm': ^2.0.0 + '@tiptap/core': ^2.5.9 + '@tiptap/pm': ^2.5.9 dependencies: '@tiptap/core': 2.2.6(@tiptap/pm@2.2.6) '@tiptap/pm': 2.2.6 @@ -8705,6 +8709,16 @@ packages: '@tiptap/pm': 2.2.6 dev: false + /@tiptap/extension-gapcursor@2.5.9(@tiptap/core@2.2.6)(@tiptap/pm@2.5.9): + resolution: {integrity: sha512-yW7V2ebezsa7mWEDWCg4A1ZGsmSV5bEHKse9wzHCDkb7TutSVhLZxGo72U6hNN9PnAksv+FJQk03NuZNYvNyRQ==} + peerDependencies: + '@tiptap/core': ^2.5.9 + '@tiptap/pm': ^2.5.9 + dependencies: + '@tiptap/core': 2.2.6(@tiptap/pm@2.5.9) + '@tiptap/pm': 2.5.9 + dev: false + /@tiptap/extension-hard-break@2.2.6(@tiptap/core@2.2.6): resolution: {integrity: sha512-gwavC76sn26XQLyDaDtf28KIcbhMYPP+C5pkbRvAhVSckQB3Ebz3GRttVbm/jp+Uifp3bmoQEzISGCONEdKQoQ==} peerDependencies: @@ -8718,7 +8732,7 @@ packages: peerDependencies: '@tiptap/core': ^2.0.0 dependencies: - '@tiptap/core': 2.2.6(@tiptap/pm@2.2.6) + '@tiptap/core': 2.2.6(@tiptap/pm@2.5.9) dev: false /@tiptap/extension-highlight@2.2.6(@tiptap/core@2.2.6): @@ -8739,6 +8753,16 @@ packages: '@tiptap/pm': 2.2.6 dev: false + /@tiptap/extension-history@2.5.9(@tiptap/core@2.2.6)(@tiptap/pm@2.5.9): + resolution: {integrity: sha512-hGPtJgoZSwnVVqi/xipC2ET/9X2G2UI/Y+M3IYV1ZlM0tCYsv4spNi3uXlZqnXRwYcBXLk5u6e/dmsy5QFbL8g==} + peerDependencies: + '@tiptap/core': ^2.5.9 + '@tiptap/pm': ^2.5.9 + dependencies: + '@tiptap/core': 2.2.6(@tiptap/pm@2.5.9) + '@tiptap/pm': 2.5.9 + dev: false + /@tiptap/extension-horizontal-rule@2.2.6(@tiptap/core@2.2.6)(@tiptap/pm@2.2.6): resolution: {integrity: sha512-zyLU+Xlk8y3yBCblE8pFwqAP2Rju1csyAu45hi3NCJ6HDGQGdjy8oh+Xa8y2kTPxRNMZARxqB+vCiEoW3YZn2A==} peerDependencies: @@ -8749,6 +8773,16 @@ packages: '@tiptap/pm': 2.2.6 dev: false + /@tiptap/extension-horizontal-rule@2.2.6(@tiptap/core@2.2.6)(@tiptap/pm@2.5.9): + resolution: {integrity: sha512-zyLU+Xlk8y3yBCblE8pFwqAP2Rju1csyAu45hi3NCJ6HDGQGdjy8oh+Xa8y2kTPxRNMZARxqB+vCiEoW3YZn2A==} + peerDependencies: + '@tiptap/core': ^2.0.0 + '@tiptap/pm': ^2.0.0 + dependencies: + '@tiptap/core': 2.2.6(@tiptap/pm@2.5.9) + '@tiptap/pm': 2.5.9 + dev: false + /@tiptap/extension-image@2.2.6(@tiptap/core@2.2.6): resolution: {integrity: sha512-MoDVjvi0AgYYSY9QR3ff2TOKk9IVVfh+BInmLCrwejSE2q8N3p/vSI+N1GKLEfW9mqn1zdI95ev17Z12Avwv7A==} peerDependencies: @@ -8910,14 +8944,14 @@ packages: '@tiptap/core': 2.2.6(@tiptap/pm@2.2.6) dev: false - /@tiptap/html@2.2.6(@tiptap/core@2.2.6)(@tiptap/pm@2.2.6): + /@tiptap/html@2.2.6(@tiptap/core@2.2.6)(@tiptap/pm@2.5.9): resolution: {integrity: sha512-RdZ5Zr2b+LShyKaQKlWB3eLSzznH54Er8/78wKLuudE2xiUS1t25O1YgIrGUA1AFC1woSPJsS1uEvxwvKqE6eg==} peerDependencies: '@tiptap/core': ^2.0.0 '@tiptap/pm': ^2.0.0 dependencies: - '@tiptap/core': 2.2.6(@tiptap/pm@2.2.6) - '@tiptap/pm': 2.2.6 + '@tiptap/core': 2.2.6(@tiptap/pm@2.5.9) + '@tiptap/pm': 2.5.9 zeed-dom: 0.10.11 dev: false @@ -8929,37 +8963,60 @@ packages: prosemirror-commands: 1.5.2 prosemirror-dropcursor: 1.8.1 prosemirror-gapcursor: 1.3.2 - prosemirror-history: 1.3.2 + prosemirror-history: 1.4.1 + prosemirror-inputrules: 1.4.0 + prosemirror-keymap: 1.2.2 + prosemirror-markdown: 1.13.0 + prosemirror-menu: 1.2.4 + prosemirror-model: 1.22.3 + prosemirror-schema-basic: 1.2.3 + prosemirror-schema-list: 1.4.1 + prosemirror-state: 1.4.3 + prosemirror-tables: 1.4.0 + prosemirror-trailing-node: 2.0.9(prosemirror-model@1.22.3)(prosemirror-state@1.4.3)(prosemirror-view@1.33.9) + prosemirror-transform: 1.9.0 + prosemirror-view: 1.33.9 + dev: false + + /@tiptap/pm@2.5.9: + resolution: {integrity: sha512-YSUaEQVtvZnGzGjif2Tl2o9utE+6tR2Djhz0EqFUcAUEVhOMk7UYUO+r/aPfcCRraIoKKuDQzyCpjKmJicjCUA==} + dependencies: + prosemirror-changeset: 2.2.1 + prosemirror-collab: 1.3.1 + prosemirror-commands: 1.5.2 + prosemirror-dropcursor: 1.8.1 + prosemirror-gapcursor: 1.3.2 + prosemirror-history: 1.4.1 prosemirror-inputrules: 1.4.0 prosemirror-keymap: 1.2.2 - prosemirror-markdown: 1.12.0 + prosemirror-markdown: 1.13.0 prosemirror-menu: 1.2.4 - prosemirror-model: 1.19.4 - prosemirror-schema-basic: 1.2.2 - prosemirror-schema-list: 1.3.0 + prosemirror-model: 1.22.3 + prosemirror-schema-basic: 1.2.3 + prosemirror-schema-list: 1.4.1 prosemirror-state: 1.4.3 - prosemirror-tables: 1.3.5 - prosemirror-trailing-node: 2.0.7(prosemirror-model@1.19.4)(prosemirror-state@1.4.3)(prosemirror-view@1.33.1) - prosemirror-transform: 1.8.0 - prosemirror-view: 1.33.1 + prosemirror-tables: 1.4.0 + prosemirror-trailing-node: 2.0.9(prosemirror-model@1.22.3)(prosemirror-state@1.4.3)(prosemirror-view@1.33.9) + prosemirror-transform: 1.9.0 + prosemirror-view: 1.33.9 dev: false - /@tiptap/starter-kit@2.2.3(@tiptap/pm@2.2.6): + /@tiptap/starter-kit@2.2.3(@tiptap/pm@2.5.9): resolution: {integrity: sha512-Jx+QXz0SE1y+j498TqYEJcjbIV9YSMwcuIJQ04q8KqHuSmZrq9B22Qa4d0fpcM7uL7dLI4AcRrcqaOuIahCJYQ==} dependencies: - '@tiptap/core': 2.2.6(@tiptap/pm@2.2.6) + '@tiptap/core': 2.2.6(@tiptap/pm@2.5.9) '@tiptap/extension-blockquote': 2.2.6(@tiptap/core@2.2.6) '@tiptap/extension-bold': 2.2.6(@tiptap/core@2.2.6) '@tiptap/extension-bullet-list': 2.2.6(@tiptap/core@2.2.6) '@tiptap/extension-code': 2.2.6(@tiptap/core@2.2.6) - '@tiptap/extension-code-block': 2.2.3(@tiptap/core@2.2.6)(@tiptap/pm@2.2.6) + '@tiptap/extension-code-block': 2.2.3(@tiptap/core@2.2.6)(@tiptap/pm@2.5.9) '@tiptap/extension-document': 2.2.6(@tiptap/core@2.2.6) - '@tiptap/extension-dropcursor': 2.2.6(@tiptap/core@2.2.6)(@tiptap/pm@2.2.6) - '@tiptap/extension-gapcursor': 2.2.6(@tiptap/core@2.2.6)(@tiptap/pm@2.2.6) + '@tiptap/extension-dropcursor': 2.5.9(@tiptap/core@2.2.6)(@tiptap/pm@2.5.9) + '@tiptap/extension-gapcursor': 2.5.9(@tiptap/core@2.2.6)(@tiptap/pm@2.5.9) '@tiptap/extension-hard-break': 2.2.6(@tiptap/core@2.2.6) '@tiptap/extension-heading': 2.2.3(@tiptap/core@2.2.6) - '@tiptap/extension-history': 2.2.6(@tiptap/core@2.2.6)(@tiptap/pm@2.2.6) - '@tiptap/extension-horizontal-rule': 2.2.6(@tiptap/core@2.2.6)(@tiptap/pm@2.2.6) + '@tiptap/extension-history': 2.5.9(@tiptap/core@2.2.6)(@tiptap/pm@2.5.9) + '@tiptap/extension-horizontal-rule': 2.2.6(@tiptap/core@2.2.6)(@tiptap/pm@2.5.9) '@tiptap/extension-italic': 2.2.6(@tiptap/core@2.2.6) '@tiptap/extension-list-item': 2.2.6(@tiptap/core@2.2.6) '@tiptap/extension-ordered-list': 2.2.6(@tiptap/core@2.2.6) @@ -9265,14 +9322,6 @@ packages: resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} dev: true - /@types/object.omit@3.0.3: - resolution: {integrity: sha512-xrq4bQTBGYY2cw+gV4PzoG2Lv3L0pjZ1uXStRRDQoATOYW1lCsFQHhQ+OkPhIcQoqLjAq7gYif7D14Qaa6Zbew==} - dev: false - - /@types/object.pick@1.3.4: - resolution: {integrity: sha512-5PjwB0uP2XDp3nt5u5NJAG2DORHIRClPzWT/TTZhJ2Ekwe8M5bA9tvPdi9NO/n2uvu2/ictat8kgqvLfcIE1SA==} - dev: false - /@types/parse5@6.0.3: resolution: {integrity: sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==} dev: false @@ -9358,10 +9407,6 @@ packages: minipass: 4.2.8 dev: false - /@types/throttle-debounce@2.1.0: - resolution: {integrity: sha512-5eQEtSCoESnh2FsiLTxE121IiE60hnMqcb435fShf4bpLRjEu1Eoekht23y6zXS9Ts3l+Szu3TARnTsA0GkOkQ==} - dev: false - /@types/trusted-types@2.0.7: resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} dev: false @@ -9962,16 +10007,16 @@ packages: - rollup dev: false - /@vrite/tiptap-solid@1.0.2(@tiptap/core@2.2.6)(@tiptap/pm@2.2.6)(solid-js@1.8.14): - resolution: {integrity: sha512-uh6AJ+fA1u4zEBLJ5GTqwBbK1SjK7pNGjx16WzJ05ZA9FuXEVkQ9nzd3fYIHT1lyqo1arkGSDWlgn7Plidmfqw==} + /@vrite/tiptap-solid@1.0.4(@tiptap/core@2.2.6)(@tiptap/pm@2.2.6)(solid-js@1.8.14): + resolution: {integrity: sha512-kvuH3UwBjltFRzkl1po/xfACR5VwW65wYbr7lpDCHuVUGCGJczAUgy+HeWT9urlZTQlLjH2qupGU7ifXf17K5w==} peerDependencies: - '@tiptap/core': 2.4.0 - '@tiptap/pm': 2.4.0 - solid-js: ^1.8.17 + '@tiptap/core': 2.5.9 + '@tiptap/pm': 2.5.9 + solid-js: ^1.8.20 dependencies: '@tiptap/core': 2.2.6(@tiptap/pm@2.2.6) - '@tiptap/extension-bubble-menu': 2.4.0(@tiptap/core@2.2.6)(@tiptap/pm@2.2.6) - '@tiptap/extension-floating-menu': 2.4.0(@tiptap/core@2.2.6)(@tiptap/pm@2.2.6) + '@tiptap/extension-bubble-menu': 2.5.9(@tiptap/core@2.2.6)(@tiptap/pm@2.2.6) + '@tiptap/extension-floating-menu': 2.5.9(@tiptap/core@2.2.6)(@tiptap/pm@2.2.6) '@tiptap/pm': 2.2.6 nanoid: 5.0.7 solid-js: 1.8.14 @@ -10938,11 +10983,6 @@ packages: /caniuse-lite@1.0.30001642: resolution: {integrity: sha512-3XQ0DoRgLijXJErLSl+bLnJ+Et4KqV1PY6JJBGAFlsNsz31zeAIncyeZfLCabHK/jtSh+671RM9YMldxjUPZtA==} - /case-anything@2.1.13: - resolution: {integrity: sha512-zlOQ80VrQ2Ue+ymH5OuM/DlDq64mEm+B9UTdHULv5osUMD6HalNTblf2b1u/m6QecjsnOkBpqVZ+XPwIVsy7Ng==} - engines: {node: '>=12.13'} - dev: false - /ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -11468,10 +11508,6 @@ packages: type: 1.2.0 dev: false - /dash-get@1.0.2: - resolution: {integrity: sha512-4FbVrHDwfOASx7uQVxeiCTo7ggSdYZbqs8lH+WU6ViypPlDbe9y6IP5VVUDQBv9DcnyaiPT5XT0UWHgJ64zLeQ==} - dev: false - /date-fns@2.30.0: resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} engines: {node: '>=0.11'} @@ -14254,13 +14290,6 @@ packages: resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} engines: {node: '>=0.10.0'} - /is-extendable@1.0.1: - resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==} - engines: {node: '>=0.10.0'} - dependencies: - is-plain-object: 2.0.4 - dev: false - /is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -14329,13 +14358,6 @@ packages: resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} engines: {node: '>=12'} - /is-plain-object@2.0.4: - resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} - engines: {node: '>=0.10.0'} - dependencies: - isobject: 3.0.1 - dev: false - /is-promise@2.2.2: resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} dev: false @@ -14431,11 +14453,6 @@ packages: /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - /isobject@3.0.1: - resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} - engines: {node: '>=0.10.0'} - dev: false - /isomorphic-unfetch@3.1.0: resolution: {integrity: sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==} dependencies: @@ -14955,10 +14972,6 @@ packages: '@jridgewell/sourcemap-codec': 1.5.0 dev: false - /make-error@1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - dev: false - /make-synchronized@0.2.8: resolution: {integrity: sha512-jtXnKYCxjmGaXiZhXbDbGPbh4YyTvIIbOgcQjtAboc4RSm9k3nyhTFvFQB0cfs7QFKuZXKe2D2RvOkv1c+vpxg==} dev: false @@ -16674,20 +16687,6 @@ packages: object-keys: 1.1.1 dev: true - /object.omit@3.0.0: - resolution: {integrity: sha512-EO+BCv6LJfu+gBIF3ggLicFebFLN5zqzz/WWJlMFfkMyGth+oBkhxzDl0wx2W4GkLzuQs/FsSkXZb2IMWQqmBQ==} - engines: {node: '>=0.10.0'} - dependencies: - is-extendable: 1.0.1 - dev: false - - /object.pick@1.3.0: - resolution: {integrity: sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==} - engines: {node: '>=0.10.0'} - dependencies: - isobject: 3.0.1 - dev: false - /object.values@1.1.7: resolution: {integrity: sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==} engines: {node: '>= 0.4'} @@ -17629,7 +17628,7 @@ packages: /prosemirror-changeset@2.2.1: resolution: {integrity: sha512-J7msc6wbxB4ekDFj+n9gTW/jav/p53kdlivvuppHsrZXCaQdVgRghoZbSS3kwrRyAstRVQ4/+u5k7YfLgkkQvQ==} dependencies: - prosemirror-transform: 1.8.0 + prosemirror-transform: 1.9.0 dev: false /prosemirror-collab@1.3.1: @@ -17641,34 +17640,34 @@ packages: /prosemirror-commands@1.5.2: resolution: {integrity: sha512-hgLcPaakxH8tu6YvVAaILV2tXYsW3rAdDR8WNkeKGcgeMVQg3/TMhPdVoh7iAmfgVjZGtcOSjKiQaoeKjzd2mQ==} dependencies: - prosemirror-model: 1.19.4 + prosemirror-model: 1.22.3 prosemirror-state: 1.4.3 - prosemirror-transform: 1.8.0 + prosemirror-transform: 1.9.0 dev: false /prosemirror-dropcursor@1.8.1: resolution: {integrity: sha512-M30WJdJZLyXHi3N8vxN6Zh5O8ZBbQCz0gURTfPmTIBNQ5pxrdU7A58QkNqfa98YEjSAL1HUyyU34f6Pm5xBSGw==} dependencies: prosemirror-state: 1.4.3 - prosemirror-transform: 1.8.0 - prosemirror-view: 1.33.1 + prosemirror-transform: 1.9.0 + prosemirror-view: 1.33.9 dev: false /prosemirror-gapcursor@1.3.2: resolution: {integrity: sha512-wtjswVBd2vaQRrnYZaBCbyDqr232Ed4p2QPtRIUK5FuqHYKGWkEwl08oQM4Tw7DOR0FsasARV5uJFvMZWxdNxQ==} dependencies: prosemirror-keymap: 1.2.2 - prosemirror-model: 1.19.4 + prosemirror-model: 1.22.3 prosemirror-state: 1.4.3 - prosemirror-view: 1.33.1 + prosemirror-view: 1.33.9 dev: false - /prosemirror-history@1.3.2: - resolution: {integrity: sha512-/zm0XoU/N/+u7i5zepjmZAEnpvjDtzoPWW6VmKptcAnPadN/SStsBjMImdCEbb3seiNTpveziPTIrXQbHLtU1g==} + /prosemirror-history@1.4.1: + resolution: {integrity: sha512-2JZD8z2JviJrboD9cPuX/Sv/1ChFng+xh2tChQ2X4bB2HeK+rra/bmJ3xGntCcjhOqIzSDG6Id7e8RJ9QPXLEQ==} dependencies: prosemirror-state: 1.4.3 - prosemirror-transform: 1.8.0 - prosemirror-view: 1.33.1 + prosemirror-transform: 1.9.0 + prosemirror-view: 1.33.9 rope-sequence: 1.3.4 dev: false @@ -17676,7 +17675,7 @@ packages: resolution: {integrity: sha512-6ygpPRuTJ2lcOXs9JkefieMst63wVJBgHZGl5QOytN7oSZs3Co/BYbc3Yx9zm9H37Bxw8kVzCnDsihsVsL4yEg==} dependencies: prosemirror-state: 1.4.3 - prosemirror-transform: 1.8.0 + prosemirror-transform: 1.9.0 dev: false /prosemirror-keymap@1.2.2: @@ -17686,11 +17685,11 @@ packages: w3c-keyname: 2.2.8 dev: false - /prosemirror-markdown@1.12.0: - resolution: {integrity: sha512-6F5HS8Z0HDYiS2VQDZzfZP6A0s/I0gbkJy8NCzzDMtcsz3qrfqyroMMeoSjAmOhDITyon11NbXSzztfKi+frSQ==} + /prosemirror-markdown@1.13.0: + resolution: {integrity: sha512-UziddX3ZYSYibgx8042hfGKmukq5Aljp2qoBiJRejD/8MH70siQNz5RB1TrdTPheqLMy4aCe4GYNF10/3lQS5g==} dependencies: markdown-it: 14.0.0 - prosemirror-model: 1.19.4 + prosemirror-model: 1.22.3 dev: false /prosemirror-menu@1.2.4: @@ -17698,75 +17697,74 @@ packages: dependencies: crelt: 1.0.6 prosemirror-commands: 1.5.2 - prosemirror-history: 1.3.2 + prosemirror-history: 1.4.1 prosemirror-state: 1.4.3 dev: false - /prosemirror-model@1.19.4: - resolution: {integrity: sha512-RPmVXxUfOhyFdayHawjuZCxiROsm9L4FCUA6pWI+l7n2yCBsWy9VpdE1hpDHUS8Vad661YLY9AzqfjLhAKQ4iQ==} + /prosemirror-model@1.22.3: + resolution: {integrity: sha512-V4XCysitErI+i0rKFILGt/xClnFJaohe/wrrlT2NSZ+zk8ggQfDH4x2wNK7Gm0Hp4CIoWizvXFP7L9KMaCuI0Q==} dependencies: orderedmap: 2.1.1 dev: false - /prosemirror-schema-basic@1.2.2: - resolution: {integrity: sha512-/dT4JFEGyO7QnNTe9UaKUhjDXbTNkiWTq/N4VpKaF79bBjSExVV2NXmJpcM7z/gD7mbqNjxbmWW5nf1iNSSGnw==} + /prosemirror-schema-basic@1.2.3: + resolution: {integrity: sha512-h+H0OQwZVqMon1PNn0AG9cTfx513zgIG2DY00eJ00Yvgb3UD+GQ/VlWW5rcaxacpCGT1Yx8nuhwXk4+QbXUfJA==} dependencies: - prosemirror-model: 1.19.4 + prosemirror-model: 1.22.3 dev: false - /prosemirror-schema-list@1.3.0: - resolution: {integrity: sha512-Hz/7gM4skaaYfRPNgr421CU4GSwotmEwBVvJh5ltGiffUJwm7C8GfN/Bc6DR1EKEp5pDKhODmdXXyi9uIsZl5A==} + /prosemirror-schema-list@1.4.1: + resolution: {integrity: sha512-jbDyaP/6AFfDfu70VzySsD75Om2t3sXTOdl5+31Wlxlg62td1haUpty/ybajSfJ1pkGadlOfwQq9kgW5IMo1Rg==} dependencies: - prosemirror-model: 1.19.4 + prosemirror-model: 1.22.3 prosemirror-state: 1.4.3 - prosemirror-transform: 1.8.0 + prosemirror-transform: 1.9.0 dev: false /prosemirror-state@1.4.3: resolution: {integrity: sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==} dependencies: - prosemirror-model: 1.19.4 - prosemirror-transform: 1.8.0 - prosemirror-view: 1.33.1 + prosemirror-model: 1.22.3 + prosemirror-transform: 1.9.0 + prosemirror-view: 1.33.9 dev: false - /prosemirror-tables@1.3.5: - resolution: {integrity: sha512-JSZ2cCNlApu/ObAhdPyotrjBe2cimniniTpz60YXzbL0kZ+47nEYk2LWbfKU2lKpBkUNquta2PjteoNi4YCluQ==} + /prosemirror-tables@1.4.0: + resolution: {integrity: sha512-fxryZZkQG12fSCNuZDrYx6Xvo2rLYZTbKLRd8rglOPgNJGMKIS8uvTt6gGC38m7UCu/ENnXIP9pEz5uDaPc+cA==} dependencies: prosemirror-keymap: 1.2.2 - prosemirror-model: 1.19.4 + prosemirror-model: 1.22.3 prosemirror-state: 1.4.3 - prosemirror-transform: 1.8.0 - prosemirror-view: 1.33.1 + prosemirror-transform: 1.9.0 + prosemirror-view: 1.33.9 dev: false - /prosemirror-trailing-node@2.0.7(prosemirror-model@1.19.4)(prosemirror-state@1.4.3)(prosemirror-view@1.33.1): - resolution: {integrity: sha512-8zcZORYj/8WEwsGo6yVCRXFMOfBo0Ub3hCUvmoWIZYfMP26WqENU0mpEP27w7mt8buZWuGrydBewr0tOArPb1Q==} + /prosemirror-trailing-node@2.0.9(prosemirror-model@1.22.3)(prosemirror-state@1.4.3)(prosemirror-view@1.33.9): + resolution: {integrity: sha512-YvyIn3/UaLFlFKrlJB6cObvUhmwFNZVhy1Q8OpW/avoTbD/Y7H5EcjK4AZFKhmuS6/N6WkGgt7gWtBWDnmFvHg==} peerDependencies: - prosemirror-model: ^1.19.0 + prosemirror-model: ^1.22.1 prosemirror-state: ^1.4.2 - prosemirror-view: ^1.31.2 + prosemirror-view: ^1.33.8 dependencies: '@remirror/core-constants': 2.0.2 - '@remirror/core-helpers': 3.0.0 escape-string-regexp: 4.0.0 - prosemirror-model: 1.19.4 + prosemirror-model: 1.22.3 prosemirror-state: 1.4.3 - prosemirror-view: 1.33.1 + prosemirror-view: 1.33.9 dev: false - /prosemirror-transform@1.8.0: - resolution: {integrity: sha512-BaSBsIMv52F1BVVMvOmp1yzD3u65uC3HTzCBQV1WDPqJRQ2LuHKcyfn0jwqodo8sR9vVzMzZyI+Dal5W9E6a9A==} + /prosemirror-transform@1.9.0: + resolution: {integrity: sha512-5UXkr1LIRx3jmpXXNKDhv8OyAOeLTGuXNwdVfg8x27uASna/wQkr9p6fD3eupGOi4PLJfbezxTyi/7fSJypXHg==} dependencies: - prosemirror-model: 1.19.4 + prosemirror-model: 1.22.3 dev: false - /prosemirror-view@1.33.1: - resolution: {integrity: sha512-62qkYgSJIkwIMMCpuGuPzc52DiK1Iod6TWoIMxP4ja6BTD4yO8kCUL64PZ/WhH/dJ9fW0CDO39FhH1EMyhUFEg==} + /prosemirror-view@1.33.9: + resolution: {integrity: sha512-xV1A0Vz9cIcEnwmMhKKFAOkfIp8XmJRnaZoPqNXrPS7EK5n11Ov8V76KhR0RsfQd/SIzmWY+bg+M44A2Lx/Nnw==} dependencies: - prosemirror-model: 1.19.4 + prosemirror-model: 1.22.3 prosemirror-state: 1.4.3 - prosemirror-transform: 1.8.0 + prosemirror-transform: 1.9.0 dev: false /proto-list@1.2.4: @@ -19549,11 +19547,6 @@ packages: real-require: 0.2.0 dev: false - /throttle-debounce@3.0.1: - resolution: {integrity: sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==} - engines: {node: '>=10'} - dev: false - /timers-ext@0.1.7: resolution: {integrity: sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==} dependencies: @@ -21038,7 +21031,7 @@ packages: engines: {node: '>=0.4'} dev: false - /y-prosemirror@1.2.2(prosemirror-model@1.19.4)(prosemirror-state@1.4.3)(prosemirror-view@1.33.1)(y-protocols@1.0.6)(yjs@13.6.11): + /y-prosemirror@1.2.2(prosemirror-model@1.22.3)(prosemirror-state@1.4.3)(prosemirror-view@1.33.9)(y-protocols@1.0.6)(yjs@13.6.11): resolution: {integrity: sha512-hHdnIAhfa8mIoLWtTkMDb6RBzN3lye1QVkaZwVm58sledAA1zTl+yyEtgkrY/sdH6SaQL0rsLj61zHjgr5D0HQ==} engines: {node: '>=16.0.0', npm: '>=8.0.0'} peerDependencies: @@ -21049,9 +21042,9 @@ packages: yjs: ^13.5.38 dependencies: lib0: 0.2.94 - prosemirror-model: 1.19.4 + prosemirror-model: 1.22.3 prosemirror-state: 1.4.3 - prosemirror-view: 1.33.1 + prosemirror-view: 1.33.9 y-protocols: 1.0.6(yjs@13.6.11) yjs: 13.6.11 dev: false