diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5260b91d..55d72719 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- **connected-solid:** Read links from Link header of a Solid resource. (#165)
+- **vue:** Add [Vue](https://vuejs.org) support with `@ldo/vue` package. ([#171](https://github.com/o-development/ldo/pull/171))
### Changed
diff --git a/dev/solid-vue-vite-app/.gitignore b/dev/solid-vue-vite-app/.gitignore
new file mode 100644
index 00000000..f22509c8
--- /dev/null
+++ b/dev/solid-vue-vite-app/.gitignore
@@ -0,0 +1,39 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+.DS_Store
+dist
+dist-ssr
+coverage
+*.local
+
+# Editor directories and files
+.vscode/*
+#!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
+
+.eslintcache
+
+# Cypress
+/cypress/videos/
+/cypress/screenshots/
+
+# Vitest
+__screenshots__/
+
+# Vite
+*.timestamp-*-*.mjs
diff --git a/dev/solid-vue-vite-app/README.md b/dev/solid-vue-vite-app/README.md
new file mode 100644
index 00000000..493f8a6f
--- /dev/null
+++ b/dev/solid-vue-vite-app/README.md
@@ -0,0 +1,42 @@
+# solid-vue-vite-app
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VS Code](https://code.visualstudio.com/) + [Vue (Official)](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
+
+## Recommended Browser Setup
+
+- Chromium-based browsers (Chrome, Edge, Brave, etc.):
+ - [Vue.js devtools](https://chromewebstore.google.com/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd)
+ - [Turn on Custom Object Formatter in Chrome DevTools](http://bit.ly/object-formatters)
+- Firefox:
+ - [Vue.js devtools](https://addons.mozilla.org/en-US/firefox/addon/vue-js-devtools/)
+ - [Turn on Custom Object Formatter in Firefox DevTools](https://fxdx.dev/firefox-devtools-custom-object-formatters/)
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) to make the TypeScript language service aware of `.vue` types.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vite.dev/config/).
+
+## Project Setup
+
+```sh
+npm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+npm run dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+npm run build
+```
diff --git a/dev/solid-vue-vite-app/env.d.ts b/dev/solid-vue-vite-app/env.d.ts
new file mode 100644
index 00000000..11f02fe2
--- /dev/null
+++ b/dev/solid-vue-vite-app/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/dev/solid-vue-vite-app/index.html b/dev/solid-vue-vite-app/index.html
new file mode 100644
index 00000000..9d30802c
--- /dev/null
+++ b/dev/solid-vue-vite-app/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/dev/solid-vue-vite-app/package.json b/dev/solid-vue-vite-app/package.json
new file mode 100644
index 00000000..61d255fe
--- /dev/null
+++ b/dev/solid-vue-vite-app/package.json
@@ -0,0 +1,37 @@
+{
+ "name": "solid-vue-vite-app",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build",
+ "build:ldo": "ldo build --input src/_shapes --output src/_ldo"
+ },
+ "dependencies": {
+ "@ldo/connected-solid": "^1.0.0-alpha.50",
+ "@ldo/ldo": "^1.0.0-alpha.50",
+ "@ldo/vue": "^1.0.0-alpha.50",
+ "vue": "^3.5.40"
+ },
+ "devDependencies": {
+ "@ldo/cli": "^1.0.0-alpha.50",
+ "@tsconfig/node24": "^24.0.4",
+ "@types/jsonld": "^1.5.15",
+ "@types/node": "^24.13.3",
+ "@types/shexj": "^2.1.7",
+ "@vitejs/plugin-vue": "^6.0.8",
+ "@vue/tsconfig": "^0.9.1",
+ "npm-run-all2": "^9.0.2",
+ "typescript": "~6.0.0",
+ "vite": "^8.1.5",
+ "vite-plugin-vue-devtools": "^8.1.5",
+ "vue-tsc": "^3.3.7"
+ },
+ "engines": {
+ "node": "^22.18.0 || >=24.12.0"
+ }
+}
diff --git a/dev/solid-vue-vite-app/public/favicon.ico b/dev/solid-vue-vite-app/public/favicon.ico
new file mode 100644
index 00000000..df36fcfb
Binary files /dev/null and b/dev/solid-vue-vite-app/public/favicon.ico differ
diff --git a/dev/solid-vue-vite-app/src/App.vue b/dev/solid-vue-vite-app/src/App.vue
new file mode 100644
index 00000000..6a95f755
--- /dev/null
+++ b/dev/solid-vue-vite-app/src/App.vue
@@ -0,0 +1,61 @@
+
+
+
+
+
vue Solid auth test
+
+
{{ subject?.name ?? subject?.["@id"] }}
+
+ -
+ {{ friend["@id"] }}
+
+
+
+
checked:
+
active:
+
webId:
+
webId resource:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dev/solid-vue-vite-app/src/_ldo/foafProfile.context.ts b/dev/solid-vue-vite-app/src/_ldo/foafProfile.context.ts
new file mode 100644
index 00000000..e7a57dfc
--- /dev/null
+++ b/dev/solid-vue-vite-app/src/_ldo/foafProfile.context.ts
@@ -0,0 +1,48 @@
+import type { LdoJsonldContext } from "@ldo/ldo";
+
+/**
+ * =============================================================================
+ * foafProfileContext: JSONLD Context for foafProfile
+ * =============================================================================
+ */
+export const foafProfileContext: LdoJsonldContext = {
+ type: {
+ "@id": "@type",
+ "@isCollection": true,
+ },
+ Person: {
+ "@id": "http://xmlns.com/foaf/0.1/Person",
+ "@context": {
+ type: {
+ "@id": "@type",
+ "@isCollection": true,
+ },
+ name: {
+ "@id": "http://xmlns.com/foaf/0.1/name",
+ "@type": "http://www.w3.org/2001/XMLSchema#string",
+ },
+ img: {
+ "@id": "http://xmlns.com/foaf/0.1/img",
+ "@type": "http://www.w3.org/2001/XMLSchema#string",
+ },
+ knows: {
+ "@id": "http://xmlns.com/foaf/0.1/knows",
+ "@type": "@id",
+ "@isCollection": true,
+ },
+ },
+ },
+ name: {
+ "@id": "http://xmlns.com/foaf/0.1/name",
+ "@type": "http://www.w3.org/2001/XMLSchema#string",
+ },
+ img: {
+ "@id": "http://xmlns.com/foaf/0.1/img",
+ "@type": "http://www.w3.org/2001/XMLSchema#string",
+ },
+ knows: {
+ "@id": "http://xmlns.com/foaf/0.1/knows",
+ "@type": "@id",
+ "@isCollection": true,
+ },
+};
diff --git a/dev/solid-vue-vite-app/src/_ldo/foafProfile.schema.ts b/dev/solid-vue-vite-app/src/_ldo/foafProfile.schema.ts
new file mode 100644
index 00000000..25243cde
--- /dev/null
+++ b/dev/solid-vue-vite-app/src/_ldo/foafProfile.schema.ts
@@ -0,0 +1,97 @@
+import type { Schema } from "shexj";
+
+/**
+ * =============================================================================
+ * foafProfileSchema: ShexJ Schema for foafProfile
+ * =============================================================================
+ */
+export const foafProfileSchema: Schema = {
+ type: "Schema",
+ shapes: [
+ {
+ id: "https://example.com/FoafProfile",
+ type: "ShapeDecl",
+ shapeExpr: {
+ type: "Shape",
+ expression: {
+ type: "EachOf",
+ expressions: [
+ {
+ type: "TripleConstraint",
+ predicate: "http://www.w3.org/1999/02/22-rdf-syntax-ns#type",
+ valueExpr: {
+ type: "NodeConstraint",
+ values: ["http://xmlns.com/foaf/0.1/Person"],
+ },
+ annotations: [
+ {
+ type: "Annotation",
+ predicate: "http://www.w3.org/2000/01/rdf-schema#comment",
+ object: {
+ value: "Defines the node as a Person (from foaf)",
+ },
+ },
+ ],
+ },
+ {
+ type: "TripleConstraint",
+ predicate: "http://xmlns.com/foaf/0.1/name",
+ valueExpr: {
+ type: "NodeConstraint",
+ datatype: "http://www.w3.org/2001/XMLSchema#string",
+ },
+ min: 0,
+ max: 1,
+ annotations: [
+ {
+ type: "Annotation",
+ predicate: "http://www.w3.org/2000/01/rdf-schema#comment",
+ object: {
+ value: "Define a person's name.",
+ },
+ },
+ ],
+ },
+ {
+ type: "TripleConstraint",
+ predicate: "http://xmlns.com/foaf/0.1/img",
+ valueExpr: {
+ type: "NodeConstraint",
+ datatype: "http://www.w3.org/2001/XMLSchema#string",
+ },
+ min: 0,
+ max: 1,
+ annotations: [
+ {
+ type: "Annotation",
+ predicate: "http://www.w3.org/2000/01/rdf-schema#comment",
+ object: {
+ value: "Photo link but in string form",
+ },
+ },
+ ],
+ },
+ {
+ type: "TripleConstraint",
+ predicate: "http://xmlns.com/foaf/0.1/knows",
+ valueExpr: "https://example.com/FoafProfile",
+ min: 0,
+ max: -1,
+ annotations: [
+ {
+ type: "Annotation",
+ predicate: "http://www.w3.org/2000/01/rdf-schema#comment",
+ object: {
+ value:
+ "A list of WebIds for all the people this user knows.",
+ },
+ },
+ ],
+ },
+ ],
+ },
+ extra: ["http://www.w3.org/1999/02/22-rdf-syntax-ns#type"],
+ },
+ },
+ ],
+};
diff --git a/dev/solid-vue-vite-app/src/_ldo/foafProfile.shapeTypes.ts b/dev/solid-vue-vite-app/src/_ldo/foafProfile.shapeTypes.ts
new file mode 100644
index 00000000..2c52ee86
--- /dev/null
+++ b/dev/solid-vue-vite-app/src/_ldo/foafProfile.shapeTypes.ts
@@ -0,0 +1,19 @@
+import type { ShapeType } from "@ldo/ldo";
+import { foafProfileSchema } from "./foafProfile.schema";
+import { foafProfileContext } from "./foafProfile.context";
+import type { FoafProfile } from "./foafProfile.typings";
+
+/**
+ * =============================================================================
+ * LDO ShapeTypes foafProfile
+ * =============================================================================
+ */
+
+/**
+ * FoafProfile ShapeType
+ */
+export const FoafProfileShapeType: ShapeType = {
+ schema: foafProfileSchema,
+ shape: "https://example.com/FoafProfile",
+ context: foafProfileContext,
+};
diff --git a/dev/solid-vue-vite-app/src/_ldo/foafProfile.typings.ts b/dev/solid-vue-vite-app/src/_ldo/foafProfile.typings.ts
new file mode 100644
index 00000000..16843881
--- /dev/null
+++ b/dev/solid-vue-vite-app/src/_ldo/foafProfile.typings.ts
@@ -0,0 +1,33 @@
+import type { LdoJsonldContext, LdSet } from "@ldo/ldo";
+
+/**
+ * =============================================================================
+ * Typescript Typings for foafProfile
+ * =============================================================================
+ */
+
+/**
+ * FoafProfile Type
+ */
+export interface FoafProfile {
+ "@id"?: string;
+ "@context"?: LdoJsonldContext;
+ /**
+ * Defines the node as a Person (from foaf)
+ */
+ type: LdSet<{
+ "@id": "Person";
+ }>;
+ /**
+ * Define a person's name.
+ */
+ name?: string;
+ /**
+ * Photo link but in string form
+ */
+ img?: string;
+ /**
+ * A list of WebIds for all the people this user knows.
+ */
+ knows?: LdSet;
+}
diff --git a/dev/solid-vue-vite-app/src/_shapes/foafProfile.shex b/dev/solid-vue-vite-app/src/_shapes/foafProfile.shex
new file mode 100644
index 00000000..dff09d16
--- /dev/null
+++ b/dev/solid-vue-vite-app/src/_shapes/foafProfile.shex
@@ -0,0 +1,19 @@
+# This shape is provided by default as an example
+# You can create your own shape to fit your needs using ShEx (https://shex.io)
+# Also check out https://shaperepo.com for examples of more shapes.
+
+PREFIX ex:
+PREFIX foaf:
+PREFIX rdfs:
+PREFIX xsd:
+
+ex:FoafProfile EXTRA a {
+ a [ foaf:Person ]
+ // rdfs:comment "Defines the node as a Person (from foaf)" ;
+ foaf:name xsd:string ?
+ // rdfs:comment "Define a person's name." ;
+ foaf:img xsd:string ?
+ // rdfs:comment "Photo link but in string form" ;
+ foaf:knows @ex:FoafProfile *
+ // rdfs:comment "A list of WebIds for all the people this user knows." ;
+}
diff --git a/dev/solid-vue-vite-app/src/ldo.ts b/dev/solid-vue-vite-app/src/ldo.ts
new file mode 100644
index 00000000..54680072
--- /dev/null
+++ b/dev/solid-vue-vite-app/src/ldo.ts
@@ -0,0 +1,5 @@
+import { createLdoVueMethods } from "@ldo/vue";
+import { solidConnectedPlugin } from "@ldo/connected-solid";
+
+export const { dataset, useSubject, useResource, useMatchSubject } =
+ createLdoVueMethods([solidConnectedPlugin]);
diff --git a/dev/solid-vue-vite-app/src/main.ts b/dev/solid-vue-vite-app/src/main.ts
new file mode 100644
index 00000000..b670de8b
--- /dev/null
+++ b/dev/solid-vue-vite-app/src/main.ts
@@ -0,0 +1,4 @@
+import { createApp } from "vue";
+import App from "./App.vue";
+
+createApp(App).mount("#app");
diff --git a/dev/solid-vue-vite-app/src/useMatchSubjectTest.vue b/dev/solid-vue-vite-app/src/useMatchSubjectTest.vue
new file mode 100644
index 00000000..a77ee401
--- /dev/null
+++ b/dev/solid-vue-vite-app/src/useMatchSubjectTest.vue
@@ -0,0 +1,61 @@
+
+
+
+
+
diff --git a/dev/solid-vue-vite-app/src/vueReadmeTest.vue b/dev/solid-vue-vite-app/src/vueReadmeTest.vue
new file mode 100644
index 00000000..4a01df39
--- /dev/null
+++ b/dev/solid-vue-vite-app/src/vueReadmeTest.vue
@@ -0,0 +1,37 @@
+
+
+
+
+
+ type: {{ resource.type }}
+
+ isError: {{ resource.isError }}
+
+ isFetched: {{ resource.isFetched() }}
+
+ isLoading:
+ {{ resource.isLoading() }}
+
+ Name: {{ subject?.name }}
+
+ Friends:
+
+ -
+ {{ friend["@id"] }}
+
+
+
+
diff --git a/dev/solid-vue-vite-app/tsconfig.app.json b/dev/solid-vue-vite-app/tsconfig.app.json
new file mode 100644
index 00000000..c0f2d867
--- /dev/null
+++ b/dev/solid-vue-vite-app/tsconfig.app.json
@@ -0,0 +1,18 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ // Extra safety for array and object lookups, but may have false positives.
+ "noUncheckedIndexedAccess": true,
+
+ // Path mapping for cleaner imports.
+ "paths": {
+ "@/*": ["./src/*"]
+ },
+
+ // `vue-tsc --build` produces a .tsbuildinfo file for incremental type-checking.
+ // Specified here to keep it out of the root directory.
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo"
+ }
+}
diff --git a/dev/solid-vue-vite-app/tsconfig.json b/dev/solid-vue-vite-app/tsconfig.json
new file mode 100644
index 00000000..66b5e570
--- /dev/null
+++ b/dev/solid-vue-vite-app/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ }
+ ]
+}
diff --git a/dev/solid-vue-vite-app/tsconfig.node.json b/dev/solid-vue-vite-app/tsconfig.node.json
new file mode 100644
index 00000000..c9b2badc
--- /dev/null
+++ b/dev/solid-vue-vite-app/tsconfig.node.json
@@ -0,0 +1,27 @@
+// TSConfig for modules that run in Node.js environment via either transpilation or type-stripping.
+{
+ "extends": "@tsconfig/node24/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "playwright.config.*",
+ "eslint.config.*"
+ ],
+ "compilerOptions": {
+ // Most tools use transpilation instead of Node.js's native type-stripping.
+ // Bundler mode provides a smoother developer experience.
+ "module": "preserve",
+ "moduleResolution": "bundler",
+
+ // Include Node.js types and avoid accidentally including other `@types/*` packages.
+ "types": ["node"],
+
+ // Disable emitting output during `vue-tsc --build`, which is used for type-checking only.
+ "noEmit": true,
+
+ // `vue-tsc --build` produces a .tsbuildinfo file for incremental type-checking.
+ // Specified here to keep it out of the root directory.
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo"
+ }
+}
diff --git a/dev/solid-vue-vite-app/vite.config.ts b/dev/solid-vue-vite-app/vite.config.ts
new file mode 100644
index 00000000..74831822
--- /dev/null
+++ b/dev/solid-vue-vite-app/vite.config.ts
@@ -0,0 +1,15 @@
+import { fileURLToPath, URL } from "node:url";
+
+import { defineConfig } from "vite";
+import vue from "@vitejs/plugin-vue";
+import vueDevTools from "vite-plugin-vue-devtools";
+
+// https://vite.dev/config/
+export default defineConfig({
+ plugins: [vue(), vueDevTools()],
+ resolve: {
+ alias: {
+ "@": fileURLToPath(new URL("./src", import.meta.url)),
+ },
+ },
+});
diff --git a/package-lock.json b/package-lock.json
index 379b43a4..ae1ebce1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -448,6 +448,159 @@
"url": "https://github.com/sponsors/Boshen"
}
},
+ "dev/solid-react-vite-app/node_modules/@rolldown/binding-android-arm64": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.2.tgz",
+ "integrity": "sha512-ZS4D1JPGn/MYQN/SYDWftIE/nVsM8j/AFOYEzAoOE2O3NktQOZru+/vYXGbR/qtdLdIfGCP0lcoJiYVzsEz+iQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "dev/solid-react-vite-app/node_modules/@rolldown/binding-darwin-arm64": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.2.tgz",
+ "integrity": "sha512-vdFA9+C/rekyGce7WqHs/xoT0ioZEWaOFyZLIV1mEeNFaFDUQrPIo8Vs2GvJ6eetb3rzDUtUBgzto3ExpXJB3w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "dev/solid-react-vite-app/node_modules/@rolldown/binding-darwin-x64": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.2.tgz",
+ "integrity": "sha512-BewSOwTHazv77DTYiAZXSqqKZ4KP/KonFisDMVU7PImxoWfB2aepnPhd2E4SWz3zDzYgDNbs6jBmTdgNnF02GA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "dev/solid-react-vite-app/node_modules/@rolldown/binding-freebsd-x64": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.2.tgz",
+ "integrity": "sha512-m41o7M0YWtUdqk61Tb+jnKb2rN++iRdIASlExkUoKfIAH30DOHCB8fVLzSUpbWHHU8esmEioY62PxzexE8MBuA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "dev/solid-react-vite-app/node_modules/@rolldown/binding-linux-arm-gnueabihf": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.2.tgz",
+ "integrity": "sha512-jcojB9H7W/jS29pMKWAK1N+fU99vXodHDTatS3b3y/XSOCiHo0kkA74pL3jJmkoQtYpOCxDvaKs1fo2Ij/1X5w==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "dev/solid-react-vite-app/node_modules/@rolldown/binding-linux-arm64-gnu": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.2.tgz",
+ "integrity": "sha512-1jn6qDU5iiOgFgygDzKUuKP0maTi0/f1+sBLgvij/76C77Nm3ts6ufz9Bjg5q5dduxiUIxtq86JIoBvo1xQ4Ig==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "dev/solid-react-vite-app/node_modules/@rolldown/binding-linux-arm64-musl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.2.tgz",
+ "integrity": "sha512-QVLO/czFMdoMFSqlX3bcswcJNm/23r+qoa/jgtmFc/qEp6/jXmIkDjF/XIo8dPfGaiwy1xfQn8o77L79GeXFgw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "dev/solid-react-vite-app/node_modules/@rolldown/binding-linux-ppc64-gnu": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.2.tgz",
+ "integrity": "sha512-hgO5Abm0w5UL6FEa2iFnZqo2KlK7TQ5QhV5x09hujBf7t5KzHQ1VmfPuTpqRy/rNlSxua3eWH374xxiVrP+lcA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "dev/solid-react-vite-app/node_modules/@rolldown/binding-linux-s390x-gnu": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.2.tgz",
+ "integrity": "sha512-fy8rXxuYEu602abC8MUNaPjYLIFzReOaEIEMKMUa0rFEUxNpVXhs15KSSQ4qlqSaM7B6rcj9rDZgADh/IGDzLQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
"dev/solid-react-vite-app/node_modules/@rolldown/binding-linux-x64-gnu": {
"version": "1.0.2",
"cpu": [
@@ -478,6 +631,57 @@
"node": "^20.19.0 || >=22.12.0"
}
},
+ "dev/solid-react-vite-app/node_modules/@rolldown/binding-openharmony-arm64": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.2.tgz",
+ "integrity": "sha512-1v5vHasdfQAZoEHakBV72LIFAC9JjnymsiKxp+GEr/ma3+NJCPSaYK+qavInOovJkgwFrs7GccX2d6IgDA3Z5w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "dev/solid-react-vite-app/node_modules/@rolldown/binding-win32-arm64-msvc": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.2.tgz",
+ "integrity": "sha512-SqKonF56vA/L2yHwHYcEp2P34URpOZ7d1fS635cTkpDnUtEGdUbhI6NzsPdqeSWvAAeGDrxjWjNmibDIdFf9/A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "dev/solid-react-vite-app/node_modules/@rolldown/binding-win32-x64-msvc": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.2.tgz",
+ "integrity": "sha512-v7qRI7gXLRINcOGXt+7YmAZ6iFuyZVMIoXAxhd8oP+DR9dLfL9GfNIx7PLMxmhZdvq8waUJBQiWN9EKNy+TRBQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
"dev/solid-react-vite-app/node_modules/@rolldown/plugin-babel": {
"version": "0.2.3",
"dev": true,
@@ -888,6 +1092,329 @@
}
}
},
+ "dev/solid-vue-app": {
+ "version": "0.0.0",
+ "extraneous": true,
+ "dependencies": {
+ "vue": "^3.5.40"
+ },
+ "devDependencies": {
+ "@tsconfig/node24": "^24.0.4",
+ "@types/node": "^24.13.3",
+ "@vitejs/plugin-vue": "^6.0.8",
+ "@vue/tsconfig": "^0.9.1",
+ "npm-run-all2": "^9.0.2",
+ "typescript": "~6.0.0",
+ "vite": "^8.1.5",
+ "vite-plugin-vue-devtools": "^8.1.5",
+ "vue-tsc": "^3.3.7"
+ },
+ "engines": {
+ "node": "^22.18.0 || >=24.12.0"
+ }
+ },
+ "dev/solid-vue-vite-app": {
+ "version": "0.0.0",
+ "dependencies": {
+ "@ldo/connected-solid": "^1.0.0-alpha.50",
+ "@ldo/ldo": "^1.0.0-alpha.50",
+ "@ldo/vue": "^1.0.0-alpha.50",
+ "vue": "^3.5.40"
+ },
+ "devDependencies": {
+ "@ldo/cli": "^1.0.0-alpha.50",
+ "@tsconfig/node24": "^24.0.4",
+ "@types/jsonld": "^1.5.15",
+ "@types/node": "^24.13.3",
+ "@types/shexj": "^2.1.7",
+ "@vitejs/plugin-vue": "^6.0.8",
+ "@vue/tsconfig": "^0.9.1",
+ "npm-run-all2": "^9.0.2",
+ "typescript": "~6.0.0",
+ "vite": "^8.1.5",
+ "vite-plugin-vue-devtools": "^8.1.5",
+ "vue-tsc": "^3.3.7"
+ },
+ "engines": {
+ "node": "^22.18.0 || >=24.12.0"
+ }
+ },
+ "dev/solid-vue-vite-app/node_modules/@oxc-project/types": {
+ "version": "0.148.0",
+ "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.148.0.tgz",
+ "integrity": "sha512-Nm4s/jB+4FpFsPhWGEC4h7rzksesmtnMXomo6rCMcg/b8zLQuOziRgkCS1fxDCXOlJB/6Q8oABOZ/OP6RIPj9A==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/oxc-project"
+ }
+ },
+ "dev/solid-vue-vite-app/node_modules/@rolldown/binding-linux-x64-gnu": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.7.tgz",
+ "integrity": "sha512-r8/z8n7GFaYRln3xmP1Cxy0HH/HLM0uBUPkEuSVEfKGDA89M0FsZRZJRSwe/tJjRx+fpH/gjorfhB8tmEbSFLA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "dev/solid-vue-vite-app/node_modules/@rolldown/binding-linux-x64-musl": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.7.tgz",
+ "integrity": "sha512-pAsE8iiDxUg1xBqdhrTfg45AVDVpirjz00sblEYClGNNcMnDb+e8beQgqIAw6LvauX/APvgxUnwrgun/YYGBhw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "dev/solid-vue-vite-app/node_modules/@rolldown/pluginutils": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz",
+ "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "dev/solid-vue-vite-app/node_modules/@types/node": {
+ "version": "24.13.3",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.13.3.tgz",
+ "integrity": "sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~7.18.0"
+ }
+ },
+ "dev/solid-vue-vite-app/node_modules/@volar/language-core": {
+ "version": "2.4.28",
+ "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.28.tgz",
+ "integrity": "sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@volar/source-map": "2.4.28"
+ }
+ },
+ "dev/solid-vue-vite-app/node_modules/@volar/source-map": {
+ "version": "2.4.28",
+ "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.28.tgz",
+ "integrity": "sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "dev/solid-vue-vite-app/node_modules/@volar/typescript": {
+ "version": "2.4.28",
+ "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.28.tgz",
+ "integrity": "sha512-Ja6yvWrbis2QtN4ClAKreeUZPVYMARDYZl9LMEv1iQ1QdepB6wn0jTRxA9MftYmYa4DQ4k/DaSZpFPUfxl8giw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@volar/language-core": "2.4.28",
+ "path-browserify": "^1.0.1",
+ "vscode-uri": "^3.0.8"
+ }
+ },
+ "dev/solid-vue-vite-app/node_modules/@vue/language-core": {
+ "version": "3.3.11",
+ "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-3.3.11.tgz",
+ "integrity": "sha512-QJmpliwAVpC/OxubIByPAhNzsQPRc8/gxlN2qnVzVfIMjMDz/9RnXRFoetjz5yEgXVXyp4LqhXq3V53PjmNzFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@volar/language-core": "2.4.28",
+ "@vue/compiler-dom": "^3.5.0",
+ "@vue/shared": "^3.5.0",
+ "alien-signals": "^3.2.1",
+ "muggle-string": "^0.4.1",
+ "path-browserify": "^1.0.1",
+ "picomatch": "^4.0.4"
+ }
+ },
+ "dev/solid-vue-vite-app/node_modules/muggle-string": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz",
+ "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "dev/solid-vue-vite-app/node_modules/picomatch": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz",
+ "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "dev/solid-vue-vite-app/node_modules/rolldown": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.7.tgz",
+ "integrity": "sha512-g0EtLvBjTUB7jhyV0S/TCup3v/XSVl45vUIGbOGU4QPiyjTenCe4mKuFvW9fEgYmS2Fo42AUssRmNuMziXdrig==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@oxc-project/types": "=0.148.0",
+ "@rolldown/pluginutils": "^1.0.0"
+ },
+ "bin": {
+ "rolldown": "bin/cli.mjs"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "optionalDependencies": {
+ "@rolldown/binding-android-arm-eabi": "1.2.7",
+ "@rolldown/binding-android-arm64": "1.2.7",
+ "@rolldown/binding-darwin-arm64": "1.2.7",
+ "@rolldown/binding-darwin-x64": "1.2.7",
+ "@rolldown/binding-freebsd-x64": "1.2.7",
+ "@rolldown/binding-linux-arm-gnueabihf": "1.2.7",
+ "@rolldown/binding-linux-arm64-gnu": "1.2.7",
+ "@rolldown/binding-linux-arm64-musl": "1.2.7",
+ "@rolldown/binding-linux-ppc64-gnu": "1.2.7",
+ "@rolldown/binding-linux-s390x-gnu": "1.2.7",
+ "@rolldown/binding-linux-x64-gnu": "1.2.7",
+ "@rolldown/binding-linux-x64-musl": "1.2.7",
+ "@rolldown/binding-openharmony-arm64": "1.2.7",
+ "@rolldown/binding-win32-arm64-msvc": "1.2.7",
+ "@rolldown/binding-win32-x64-msvc": "1.2.7"
+ }
+ },
+ "dev/solid-vue-vite-app/node_modules/typescript": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz",
+ "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "dev/solid-vue-vite-app/node_modules/undici-types": {
+ "version": "7.18.2",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz",
+ "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "dev/solid-vue-vite-app/node_modules/vite": {
+ "version": "8.2.2",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-8.2.2.tgz",
+ "integrity": "sha512-cFKLV/PRgAUlIRm5WjMjJ86jrftzpqcgH+Us+DS8mI3CDNiH30Whrz8uHL3+MOLPAgqbMBAqWdAHAphOAM+z/Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "lightningcss": "^1.33.0",
+ "picomatch": "^4.0.5",
+ "postcss": "^8.5.26",
+ "rolldown": "~1.2.4",
+ "tinyglobby": "^0.2.17"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^20.19.0 || >=22.12.0",
+ "@vitejs/devtools": "^0.4.0 || ^0.5.0",
+ "esbuild": "^0.27.0 || ^0.28.0",
+ "jiti": ">=1.21.0",
+ "less": "^4.0.0",
+ "sass": "^1.70.0",
+ "sass-embedded": "^1.70.0",
+ "stylus": ">=0.54.8",
+ "sugarss": "^5.0.0",
+ "terser": "^5.16.0",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "@vitejs/devtools": {
+ "optional": true
+ },
+ "esbuild": {
+ "optional": true
+ },
+ "jiti": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ },
+ "dev/solid-vue-vite-app/node_modules/vue-tsc": {
+ "version": "3.3.11",
+ "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-3.3.11.tgz",
+ "integrity": "sha512-gOb0B9rtU2+f1dszwPqSH5kAieIF9ReeLhD3kSRNHv5WZZUQz/JdVXW0RTdqhNTMlQkqKzrTTviqKr/4FYZraQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@volar/typescript": "2.4.28",
+ "@vue/language-core": "3.3.11"
+ },
+ "bin": {
+ "vue-tsc": "bin/vue-tsc.js"
+ },
+ "peerDependencies": {
+ "typescript": ">=5.0.0"
+ }
+ },
"node_modules/@adobe/css-tools": {
"version": "4.4.4",
"dev": true,
@@ -973,11 +1500,13 @@
"license": "ISC"
},
"node_modules/@babel/code-frame": {
- "version": "7.29.0",
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz",
+ "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-validator-identifier": "^7.28.5",
+ "@babel/helper-validator-identifier": "^7.29.7",
"js-tokens": "^4.0.0",
"picocolors": "^1.1.1"
},
@@ -1031,12 +1560,14 @@
}
},
"node_modules/@babel/generator": {
- "version": "7.29.1",
+ "version": "7.29.8",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz",
+ "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/parser": "^7.29.0",
- "@babel/types": "^7.29.0",
+ "@babel/parser": "^7.29.8",
+ "@babel/types": "^7.29.8",
"@jridgewell/gen-mapping": "^0.3.12",
"@jridgewell/trace-mapping": "^0.3.28",
"jsesc": "^3.0.2"
@@ -1046,11 +1577,13 @@
}
},
"node_modules/@babel/helper-annotate-as-pure": {
- "version": "7.27.3",
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.29.7.tgz",
+ "integrity": "sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.27.3"
+ "@babel/types": "^7.29.7"
},
"engines": {
"node": ">=6.9.0"
@@ -1093,16 +1626,18 @@
"license": "ISC"
},
"node_modules/@babel/helper-create-class-features-plugin": {
- "version": "7.29.3",
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.29.7.tgz",
+ "integrity": "sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.27.3",
- "@babel/helper-member-expression-to-functions": "^7.28.5",
- "@babel/helper-optimise-call-expression": "^7.27.1",
- "@babel/helper-replace-supers": "^7.28.6",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1",
- "@babel/traverse": "^7.29.0",
+ "@babel/helper-annotate-as-pure": "^7.29.7",
+ "@babel/helper-member-expression-to-functions": "^7.29.7",
+ "@babel/helper-optimise-call-expression": "^7.29.7",
+ "@babel/helper-replace-supers": "^7.29.7",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7",
+ "@babel/traverse": "^7.29.7",
"semver": "^6.3.1"
},
"engines": {
@@ -1160,7 +1695,9 @@
}
},
"node_modules/@babel/helper-globals": {
- "version": "7.28.0",
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz",
+ "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1168,12 +1705,14 @@
}
},
"node_modules/@babel/helper-member-expression-to-functions": {
- "version": "7.28.5",
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.29.7.tgz",
+ "integrity": "sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/traverse": "^7.28.5",
- "@babel/types": "^7.28.5"
+ "@babel/traverse": "^7.29.7",
+ "@babel/types": "^7.29.7"
},
"engines": {
"node": ">=6.9.0"
@@ -1208,18 +1747,22 @@
}
},
"node_modules/@babel/helper-optimise-call-expression": {
- "version": "7.27.1",
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.29.7.tgz",
+ "integrity": "sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.27.1"
+ "@babel/types": "^7.29.7"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-plugin-utils": {
- "version": "7.28.6",
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz",
+ "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1243,13 +1786,15 @@
}
},
"node_modules/@babel/helper-replace-supers": {
- "version": "7.28.6",
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.29.7.tgz",
+ "integrity": "sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-member-expression-to-functions": "^7.28.5",
- "@babel/helper-optimise-call-expression": "^7.27.1",
- "@babel/traverse": "^7.28.6"
+ "@babel/helper-member-expression-to-functions": "^7.29.7",
+ "@babel/helper-optimise-call-expression": "^7.29.7",
+ "@babel/traverse": "^7.29.7"
},
"engines": {
"node": ">=6.9.0"
@@ -1259,28 +1804,32 @@
}
},
"node_modules/@babel/helper-skip-transparent-expression-wrappers": {
- "version": "7.27.1",
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.29.7.tgz",
+ "integrity": "sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/traverse": "^7.27.1",
- "@babel/types": "^7.27.1"
+ "@babel/traverse": "^7.29.7",
+ "@babel/types": "^7.29.7"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-string-parser": {
- "version": "7.27.1",
- "devOptional": true,
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
+ "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-identifier": {
- "version": "7.28.5",
- "devOptional": true,
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",
+ "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -1320,11 +1869,12 @@
}
},
"node_modules/@babel/parser": {
- "version": "7.29.3",
- "dev": true,
+ "version": "7.29.8",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz",
+ "integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==",
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.29.0"
+ "@babel/types": "^7.29.8"
},
"bin": {
"parser": "bin/babel-parser.js"
@@ -1422,6 +1972,24 @@
"@babel/core": "^7.0.0"
}
},
+ "node_modules/@babel/plugin-proposal-decorators": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.29.7.tgz",
+ "integrity": "sha512-EtU0Hi3GvrTqD56xKmZvV/uCXK2ZbwVNPNLAquVItcAZpUhkXwWlo3Fmj0c2LxgSf2I8IDULeAepwNP1OefLXg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-create-class-features-plugin": "^7.29.7",
+ "@babel/helper-plugin-utils": "^7.29.7",
+ "@babel/plugin-syntax-decorators": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
"node_modules/@babel/plugin-proposal-private-property-in-object": {
"version": "7.21.0-placeholder-for-preset-env.2",
"dev": true,
@@ -1433,6 +2001,22 @@
"@babel/core": "^7.0.0-0"
}
},
+ "node_modules/@babel/plugin-syntax-decorators": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.29.7.tgz",
+ "integrity": "sha512-9MTTLbF39X6sqM92JPEsoI7++26hjZvzkxKZy64aMhWLH2mPkJ/Q3AV4QLmls3R14FpSpkOwQQfUh962JGQxxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
"node_modules/@babel/plugin-syntax-import-assertions": {
"version": "7.28.6",
"dev": true,
@@ -1461,6 +2045,51 @@
"@babel/core": "^7.0.0-0"
}
},
+ "node_modules/@babel/plugin-syntax-import-meta": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
+ "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-jsx": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz",
+ "integrity": "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-typescript": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz",
+ "integrity": "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
"node_modules/@babel/plugin-syntax-unicode-sets-regex": {
"version": "7.18.6",
"dev": true,
@@ -2199,6 +2828,26 @@
"@babel/core": "^7.0.0-0"
}
},
+ "node_modules/@babel/plugin-transform-typescript": {
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.29.7.tgz",
+ "integrity": "sha512-jK52h8LaLc7JarhQV2ofeFMts4H7vnOXnqZNA6fYglBTZewRBE51KWt3BUltW1P+KoPsYkHoJeXePuz4zo2LMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.29.7",
+ "@babel/helper-create-class-features-plugin": "^7.29.7",
+ "@babel/helper-plugin-utils": "^7.29.7",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7",
+ "@babel/plugin-syntax-typescript": "^7.29.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
"node_modules/@babel/plugin-transform-unicode-escapes": {
"version": "7.27.1",
"dev": true,
@@ -2372,29 +3021,33 @@
}
},
"node_modules/@babel/template": {
- "version": "7.28.6",
+ "version": "7.29.7",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz",
+ "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/code-frame": "^7.28.6",
- "@babel/parser": "^7.28.6",
- "@babel/types": "^7.28.6"
+ "@babel/code-frame": "^7.29.7",
+ "@babel/parser": "^7.29.7",
+ "@babel/types": "^7.29.7"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/traverse": {
- "version": "7.29.0",
+ "version": "7.29.8",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.8.tgz",
+ "integrity": "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/code-frame": "^7.29.0",
- "@babel/generator": "^7.29.0",
- "@babel/helper-globals": "^7.28.0",
- "@babel/parser": "^7.29.0",
- "@babel/template": "^7.28.6",
- "@babel/types": "^7.29.0",
+ "@babel/code-frame": "^7.29.7",
+ "@babel/generator": "^7.29.8",
+ "@babel/helper-globals": "^7.29.7",
+ "@babel/parser": "^7.29.8",
+ "@babel/template": "^7.29.7",
+ "@babel/types": "^7.29.8",
"debug": "^4.3.1"
},
"engines": {
@@ -2402,12 +3055,13 @@
}
},
"node_modules/@babel/types": {
- "version": "7.29.0",
- "devOptional": true,
+ "version": "7.29.8",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz",
+ "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==",
"license": "MIT",
"dependencies": {
- "@babel/helper-string-parser": "^7.27.1",
- "@babel/helper-validator-identifier": "^7.28.5"
+ "@babel/helper-string-parser": "^7.29.7",
+ "@babel/helper-validator-identifier": "^7.29.7"
},
"engines": {
"node": ">=6.9.0"
@@ -16519,6 +17173,40 @@
"node": ">=10.0.0"
}
},
+ "node_modules/@emnapi/core": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
+ "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/wasi-threads": "1.2.1",
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@emnapi/runtime": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz",
+ "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@emnapi/wasi-threads": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz",
+ "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
"node_modules/@esbuild/linux-x64": {
"version": "0.27.7",
"cpu": [
@@ -17180,7 +17868,6 @@
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.5",
- "dev": true,
"license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
@@ -17679,6 +18366,10 @@
"resolved": "packages/type-traverser",
"link": true
},
+ "node_modules/@ldo/vue": {
+ "resolved": "packages/vue",
+ "link": true
+ },
"node_modules/@lerna/child-process": {
"version": "7.4.2",
"dev": true,
@@ -18174,6 +18865,28 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/@napi-rs/wasm-runtime": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.3.tgz",
+ "integrity": "sha512-UMduMbqO5s5zF2NkNacMT/yK5Y5QiKvWr2+50bzIIxFDwVJ2h49b+oyjaCGPhJxd2/gC2x39EHv/gHVuu36x2Q==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@tybys/wasm-util": "^0.10.3"
+ },
+ "engines": {
+ "node": "^20.19.0 || ^22.13.0 || >=23.5.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Brooooooklyn"
+ },
+ "peerDependencies": {
+ "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.4",
+ "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.4"
+ }
+ },
"node_modules/@next/env": {
"version": "16.2.6",
"license": "MIT"
@@ -18212,6 +18925,66 @@
"node": ">= 6"
}
},
+ "node_modules/@next/swc-darwin-arm64": {
+ "version": "16.2.6",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.2.6.tgz",
+ "integrity": "sha512-ZJGkkcNfYgrrMkqOdZ7zoLa1TOy0qpcMfk/z4Mh/FKUz40gVO+HNQWqmLxf67Z5WB64DRp0dhEbyHfel+6sJUg==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-darwin-x64": {
+ "version": "16.2.6",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.2.6.tgz",
+ "integrity": "sha512-v/YLBHIY132Ced3puBJ7YJKw1lqsCrgcNo2aRJlCEyQrrCeRJlvGlnmxhPxNQI3KE3N1DN5r9TPNPvka3nq5RQ==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-linux-arm64-gnu": {
+ "version": "16.2.6",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.2.6.tgz",
+ "integrity": "sha512-RPOvqlYBbcQjkz9VQQDZ2T2bARIjXZV1KFlt+V2Mr6SW/e4I9fcKsaA0hdyf2FHoTlsV2xnBd5Y912rP/1Ce6w==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-linux-arm64-musl": {
+ "version": "16.2.6",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.2.6.tgz",
+ "integrity": "sha512-URUTu1+dMkxJsPFgm+OeEvq9wf5sujw0EvgYy80TDGHTSLTnIHeqb0Eu8A3sC95IRgjejQL+kC4mw+4yPxiAXA==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
"node_modules/@next/swc-linux-x64-gnu": {
"version": "16.2.6",
"cpu": [
@@ -18240,6 +19013,36 @@
"node": ">= 10"
}
},
+ "node_modules/@next/swc-win32-arm64-msvc": {
+ "version": "16.2.6",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.2.6.tgz",
+ "integrity": "sha512-LZXpTlPyS5v7HhSmnvsLGP3iIYgYOBnc8r8ArlT55sGHV89bR2HlDdBjWQ+PY6SJMmk8TuVGFuxalnP3k/0Dwg==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-win32-x64-msvc": {
+ "version": "16.2.6",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.2.6.tgz",
+ "integrity": "sha512-F0+4i0h9J6C4eE3EAPWsoCk7UW/dbzOjyzxY0qnDUOYFu6FFmdZ6l97/XdV3/Nz3VYyO7UWjyEJUXkGqcoXfMA==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"license": "MIT",
@@ -18749,6 +19552,13 @@
"url": "https://opencollective.com/pkgr"
}
},
+ "node_modules/@polka/url": {
+ "version": "1.0.0-next.29",
+ "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz",
+ "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@publint/pack": {
"version": "0.1.4",
"dev": true,
@@ -18980,6 +19790,176 @@
"@types/node": "*"
}
},
+ "node_modules/@rolldown/binding-android-arm-eabi": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.7.tgz",
+ "integrity": "sha512-EypzgnYCwyVY4NDHKzGmNJT5b+XaQEBniHxsMdeIQLB/tcCzZnhqrzHpZFbX9iaxx+5RiB8caATBtfvZP7zVxQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-android-arm64": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.7.tgz",
+ "integrity": "sha512-l17HE9EweWaqJZhuUuNBN/FzM62xw+DECVnJyvMsxn8vJFAGLy5QfLDoYAcronkAN8VxKZHezDpulHDPx95vFw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-darwin-arm64": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.7.tgz",
+ "integrity": "sha512-8ED8ELFvHXc6OCETIn4gXObPiaR6bckM/ipXtbzlPVDRMBfEGjCKgO90F9YtfdpDatVx/ZQw7aZ1vUMf/+T3Mw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-darwin-x64": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.7.tgz",
+ "integrity": "sha512-/WPripjtiAIZ2tWY7ddijORT0Ujg87wxWW/qcoFVCKAWVDPhtY0xr7Dj0M3GyNGz60jGwTElhro/mkF9dT7dDQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-freebsd-x64": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.7.tgz",
+ "integrity": "sha512-14DI4NcqpvbICxSnGLx3PmtDaWqRP/KGSGb6C+JLLVPeZRl6dKdHba3pGsqT3vpdTqhEYIPG0MMQ8c0xYqoJxA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-arm-gnueabihf": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.7.tgz",
+ "integrity": "sha512-bxrWIRvHWQvbJwi+VIie/kDJmQxcNE6xxWwZdqF/ExVAigtHkv54WTLQPb+QsZdnFy18fg7JPfWGL0RH6vwIlQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-arm64-gnu": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.7.tgz",
+ "integrity": "sha512-toOY2BChBZyuxU7OYX6Tn389di4IzAqPTycVcci0O7FSfBqzRB3RZn+K5Is6ANf4tmgRd/K1yZTsNTXbkXsnLg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-arm64-musl": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.7.tgz",
+ "integrity": "sha512-lAIXTH/aiLRLxsTgQvfhjo4K1ydWIp00+V0voOr9beb/9ZmkUFrSIb03dXNFRgMNvkE6oGsF10ioQ6UsI+vS5Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-ppc64-gnu": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.7.tgz",
+ "integrity": "sha512-kdnwS28Pkenp/mZMRwjXXXwxQ7pIsm+bF919LUK93BOyhcLsrVKdP2p9fxpiPNPAbNuch8ypQt0pm2P2LYCAGg==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-s390x-gnu": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.7.tgz",
+ "integrity": "sha512-516OdsyLdr5E65paF3yBF55t8mfm9+gmtCsK3xI7XKXIT7EfRlHhxL8K/NR6Hu8BWSgF5+1w74lTL0+nxcc8Qw==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
"node_modules/@rolldown/binding-linux-x64-gnu": {
"version": "1.0.0-beta.9-commit.d91dfb5",
"cpu": [
@@ -19006,6 +19986,76 @@
"node": "^20.19.0 || >=22.12.0"
}
},
+ "node_modules/@rolldown/binding-openharmony-arm64": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.7.tgz",
+ "integrity": "sha512-lTcIYmmnQQA8Or/2DatS6oSqcdLHvendjS+zLu+FwgToynWMRSmQdpM65fTANJgIS4mjbMOo5KT2lnT9SAb96w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-wasm32-wasi": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.2.tgz",
+ "integrity": "sha512-mb1VobWn6NheziTk5/WEaR6AKVbrwT5sOi6C7zk3gy/pD1qtJfU1j4PgTo2NJnOtbL9Dl3Aeei8w9jJ7qC2jZQ==",
+ "cpu": [
+ "wasm32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/core": "1.10.0",
+ "@emnapi/runtime": "1.10.0",
+ "@napi-rs/wasm-runtime": "^1.1.4"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-win32-arm64-msvc": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.7.tgz",
+ "integrity": "sha512-e3Gu3WxbNk/UqQhxqU7YIYO+9ZBvWNz3U+h/qRFosscMFzdRPbXYSaSWgSnklv2fz1TgzBTcti2z35c/7irsHw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-win32-x64-msvc": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.7.tgz",
+ "integrity": "sha512-W/jg5qoRSqjsEv0+dZi4e687mcHqmVuU0P4fK6qS/xjetW2Gmc1W8j//z5nAeNcC8Ttm0hV46IjcYeuVwYhuiw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
"node_modules/@rolldown/pluginutils": {
"version": "1.0.0-beta.27",
"dev": true,
@@ -21242,6 +22292,13 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@tsconfig/node24": {
+ "version": "24.0.5",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node24/-/node24-24.0.5.tgz",
+ "integrity": "sha512-DWC54fGPuhZgg3Ighg4Y/A/bA3ZdB5hnzAuv/MkQ/X85sVsBsMQxu8t7khutdYeiNksBbFdDyeqv1HSW2Zl8aA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@tsconfig/svelte": {
"version": "5.0.8",
"dev": true,
@@ -21267,6 +22324,17 @@
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
+ "node_modules/@tybys/wasm-util": {
+ "version": "0.10.3",
+ "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz",
+ "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
"node_modules/@types/accepts": {
"version": "1.3.7",
"license": "MIT",
@@ -21506,6 +22574,8 @@
},
"node_modules/@types/jsonld": {
"version": "1.5.15",
+ "resolved": "https://registry.npmjs.org/@types/jsonld/-/jsonld-1.5.15.tgz",
+ "integrity": "sha512-PlAFPZjL+AuGYmwlqwKEL0IMP8M8RexH0NIPGfCVWSQ041H2rR/8OlyZSD7KsCVoN8vCfWdtWDBxX8yBVP+xow==",
"license": "MIT"
},
"node_modules/@types/keygrip": {
@@ -21808,6 +22878,8 @@
},
"node_modules/@types/shexj": {
"version": "2.1.7",
+ "resolved": "https://registry.npmjs.org/@types/shexj/-/shexj-2.1.7.tgz",
+ "integrity": "sha512-pu/0vIZxFTMPVjTlo5MJKFkBL/EbAuFhtCXpmBB7ZdUiyNpc6pt8GxfyRPqdf6q2SsWu71a/vbhvGK2IZN2Eug==",
"license": "MIT"
},
"node_modules/@types/spark-md5": {
@@ -21837,6 +22909,15 @@
"version": "10.0.0",
"license": "MIT"
},
+ "node_modules/@types/whatwg-mimetype": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@types/whatwg-mimetype/-/whatwg-mimetype-3.0.2.tgz",
+ "integrity": "sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "peer": true
+ },
"node_modules/@types/ws": {
"version": "8.18.1",
"license": "MIT",
@@ -22138,6 +23219,30 @@
"vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
}
},
+ "node_modules/@vitejs/plugin-vue": {
+ "version": "6.0.8",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.8.tgz",
+ "integrity": "sha512-0ZjgOg7oO6farnNGup7yvoM/YXZV84OZxHAwtflItNa/6zzQyVb5LNxyea3FEKEX2XlagIKzrlH7wwxkKgtiew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@rolldown/pluginutils": "^1.0.1"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "peerDependencies": {
+ "vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0",
+ "vue": "^3.2.25"
+ }
+ },
+ "node_modules/@vitejs/plugin-vue/node_modules/@rolldown/pluginutils": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz",
+ "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@vitest/coverage-istanbul": {
"version": "3.2.4",
"dev": true,
@@ -22287,13 +23392,67 @@
"path-browserify": "^1.0.1"
}
},
- "node_modules/@vue/compiler-core": {
- "version": "3.5.33",
+ "node_modules/@vue/babel-helper-vue-transform-on": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.5.0.tgz",
+ "integrity": "sha512-0dAYkerNhhHutHZ34JtTl2czVQHUNWv6xEbkdF5W+Yrv5pCWsqjeORdOgbtW2I9gWlt+wBmVn+ttqN9ZxR5tzA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@vue/babel-plugin-jsx": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.5.0.tgz",
+ "integrity": "sha512-mneBhw1oOqCd2247O0Yw/mRwC9jIGACAJUlawkmMBiNmL4dGA2eMzuNZVNqOUfYTa6vqmND4CtOPzmEEEqLKFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/plugin-syntax-jsx": "^7.27.1",
+ "@babel/template": "^7.27.2",
+ "@babel/traverse": "^7.28.0",
+ "@babel/types": "^7.28.2",
+ "@vue/babel-helper-vue-transform-on": "1.5.0",
+ "@vue/babel-plugin-resolve-type": "1.5.0",
+ "@vue/shared": "^3.5.18"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ },
+ "peerDependenciesMeta": {
+ "@babel/core": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vue/babel-plugin-resolve-type": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@vue/babel-plugin-resolve-type/-/babel-plugin-resolve-type-1.5.0.tgz",
+ "integrity": "sha512-Wm/60o+53JwJODm4Knz47dxJnLDJ9FnKnGZJbUUf8nQRAtt6P+undLUAVU3Ha33LxOJe6IPoifRQ6F/0RrU31w==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/parser": "^7.29.2",
- "@vue/shared": "3.5.33",
+ "@babel/code-frame": "^7.27.1",
+ "@babel/helper-module-imports": "^7.27.1",
+ "@babel/helper-plugin-utils": "^7.27.1",
+ "@babel/parser": "^7.28.0",
+ "@vue/compiler-sfc": "^3.5.18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sxzz"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@vue/compiler-core": {
+ "version": "3.5.43",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.43.tgz",
+ "integrity": "sha512-zdiLhnbe1QQqgDT8xZMpNmyqZ3qlI+/Q/FHQco57Kwl/b05HhCzN6eVGN9QU9rbga4CrS0H5SYY8VGHZCt/1Hg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.29.8",
+ "@vue/shared": "3.5.43",
"entities": "^7.0.1",
"estree-walker": "^2.0.2",
"source-map-js": "^1.2.1"
@@ -22301,7 +23460,8 @@
},
"node_modules/@vue/compiler-core/node_modules/entities": {
"version": "7.0.1",
- "dev": true,
+ "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz",
+ "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=0.12"
@@ -22312,18 +23472,104 @@
},
"node_modules/@vue/compiler-core/node_modules/estree-walker": {
"version": "2.0.2",
- "dev": true,
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
"license": "MIT"
},
"node_modules/@vue/compiler-dom": {
- "version": "3.5.33",
+ "version": "3.5.43",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.43.tgz",
+ "integrity": "sha512-PEZoAk3NQmsn/ejMzSOCyTYqwGqczrWm70PuhBKjjv1+TCoQAaO/zOqNwjV+honlNstT5ILxtc+8r8UUfj+iEQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-core": "3.5.43",
+ "@vue/shared": "3.5.43"
+ }
+ },
+ "node_modules/@vue/compiler-sfc": {
+ "version": "3.5.43",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.43.tgz",
+ "integrity": "sha512-FCbrG3XNCRl+js3huuKx4IVHBLTvMkJhVepjbxSPu1gn4yWLaYtGNQdjJGZaMytXB6qb76qQDDmDSLy/vkmleQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.29.8",
+ "@vue/compiler-core": "3.5.43",
+ "@vue/compiler-dom": "3.5.43",
+ "@vue/compiler-ssr": "3.5.43",
+ "@vue/shared": "3.5.43",
+ "estree-walker": "^2.0.2",
+ "magic-string": "^0.30.21",
+ "postcss": "^8.5.28",
+ "source-map-js": "^1.2.1"
+ }
+ },
+ "node_modules/@vue/compiler-sfc/node_modules/estree-walker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
+ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
+ "license": "MIT"
+ },
+ "node_modules/@vue/compiler-ssr": {
+ "version": "3.5.43",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.43.tgz",
+ "integrity": "sha512-GF62orf7KiJX9RqrHNGrYBudsQGD0OhJ5nDs90O8UiDuS40+YMYomiXu6w6EuvtXuRDc3MSNis3EaaSKAVSWpg==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.43",
+ "@vue/shared": "3.5.43"
+ }
+ },
+ "node_modules/@vue/devtools-core": {
+ "version": "8.2.1",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-core/-/devtools-core-8.2.1.tgz",
+ "integrity": "sha512-s/VfAY9oDTb/kFEWmy461jaFde2MIV1RO/gi1vwM+PAZBZ/Pc2Ndu3BNBdZUze8QDUuyYvElbEEGA83syjJfzA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vue/compiler-core": "3.5.33",
- "@vue/shared": "3.5.33"
+ "@vue/devtools-kit": "^8.2.1",
+ "@vue/devtools-shared": "^8.2.1"
+ },
+ "peerDependencies": {
+ "vue": "^3.0.0"
}
},
+ "node_modules/@vue/devtools-kit": {
+ "version": "8.2.1",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-8.2.1.tgz",
+ "integrity": "sha512-FIGIuq3AWReEpbAHY/cRGeHDfI0qOb8OCQ3YjbEAX04uaxIDbGc9rhkbVcG7rnfHPXE3RsU5KrWOu9V/okd8AQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/devtools-shared": "^8.2.1",
+ "birpc": "^2.6.1",
+ "hookable": "^5.5.3",
+ "perfect-debounce": "^2.0.0"
+ }
+ },
+ "node_modules/@vue/devtools-kit/node_modules/birpc": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.9.0.tgz",
+ "integrity": "sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/@vue/devtools-kit/node_modules/hookable": {
+ "version": "5.5.3",
+ "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz",
+ "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@vue/devtools-shared": {
+ "version": "8.2.1",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-8.2.1.tgz",
+ "integrity": "sha512-Fkac7lUdGReh6pVOi3AYPRGe82LQqRmAfThW7RRligOAP0ZA/Z1z9XLHDM9dv34pV2HRc79DK8uKPeG2fLnA/g==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@vue/language-core": {
"version": "1.8.27",
"dev": true,
@@ -22348,11 +23594,73 @@
}
}
},
+ "node_modules/@vue/reactivity": {
+ "version": "3.5.43",
+ "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.43.tgz",
+ "integrity": "sha512-G/c9GyOZNI2jVaaS6OX1EF1SSFSv7H0ERqNTl4+DTFMlZmB5eVAB53aLQNam/7NL2NPtaDD7RdVrzf8uJzMuOA==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/shared": "3.5.43"
+ }
+ },
+ "node_modules/@vue/runtime-core": {
+ "version": "3.5.43",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.43.tgz",
+ "integrity": "sha512-hU6U6VnVhBGQDpvlnnDlIB8ZGJBiOcgk2lh/0InltHiz3D8oSkluvuvY+do1G2H3+udeKFsmaBlgVYP7gXQzEw==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/reactivity": "3.5.43",
+ "@vue/shared": "3.5.43"
+ }
+ },
+ "node_modules/@vue/runtime-dom": {
+ "version": "3.5.43",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.43.tgz",
+ "integrity": "sha512-Bb2Jc0YjjJdMt1SJmb9b2L/IWd3I8lIT9x9eS/xvvP9CiVgna0ffua74xKRmt4/uSJ+0r4iN8ex1jrqkhQGWQw==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/reactivity": "3.5.43",
+ "@vue/runtime-core": "3.5.43",
+ "@vue/shared": "3.5.43",
+ "csstype": "^3.2.3"
+ }
+ },
+ "node_modules/@vue/server-renderer": {
+ "version": "3.5.43",
+ "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.43.tgz",
+ "integrity": "sha512-l2Ygjv9NehV94PSBxNWsAHC0j/eIIKbn92mBuWXAPGLnn6HfJ6MH5ubsd+Nk0YoZ5FRuxWI1P2VSoh+dbPQhCQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-ssr": "3.5.43",
+ "@vue/runtime-dom": "3.5.43",
+ "@vue/shared": "3.5.43"
+ }
+ },
"node_modules/@vue/shared": {
- "version": "3.5.33",
- "dev": true,
+ "version": "3.5.43",
+ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.43.tgz",
+ "integrity": "sha512-uksS7YGMR5NZyr4JNq0Rp+QyLns0ueaz20KwzIPW9R0LH1Vnt4E+XUM29PNseEbf1www2gOuhuDi5AKOIXag9Q==",
"license": "MIT"
},
+ "node_modules/@vue/tsconfig": {
+ "version": "0.9.1",
+ "resolved": "https://registry.npmjs.org/@vue/tsconfig/-/tsconfig-0.9.1.tgz",
+ "integrity": "sha512-buvjm+9NzLCJL29KY1j1991YYJ5e6275OiK+G4jtmfIb+z4POywbdm0wXusT9adVWqe0xqg70TbI7+mRx4uU9w==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "typescript": ">= 5.8",
+ "vue": "^3.4.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ },
+ "vue": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@yarnpkg/lockfile": {
"version": "1.1.0",
"dev": true,
@@ -22546,6 +23854,13 @@
"url": "https://github.com/sponsors/epoberezkin"
}
},
+ "node_modules/alien-signals": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-3.2.1.tgz",
+ "integrity": "sha512-I8FjmltrfnDFoZedi5CG8DghVYNhzb/Ijluz7tCSJH0xpd0484Kowhbb1XDYOxfJpU1p5wnM2X54dA+IfGyD1g==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/ansi-colors": {
"version": "4.1.3",
"dev": true,
@@ -23244,6 +24559,21 @@
"version": "1.1.2",
"license": "MIT"
},
+ "node_modules/buffer-image-size": {
+ "version": "0.6.4",
+ "resolved": "https://registry.npmjs.org/buffer-image-size/-/buffer-image-size-0.6.4.tgz",
+ "integrity": "sha512-nEh+kZOPY1w+gcCMobZ6ETUp9WfibndnosbpwB1iJk/8Gt5ZF2bhS6+B6bPYz424KtwsR6Rflc3tCz1/ghX2dQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "@types/node": "*"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
"node_modules/builtins": {
"version": "5.1.0",
"dev": true,
@@ -23252,6 +24582,22 @@
"semver": "^7.0.0"
}
},
+ "node_modules/bundle-name": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz",
+ "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "run-applescript": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/byte-size": {
"version": "8.1.1",
"dev": true,
@@ -24472,7 +25818,6 @@
},
"node_modules/csstype": {
"version": "3.2.3",
- "dev": true,
"license": "MIT"
},
"node_modules/damerau-levenshtein": {
@@ -24675,6 +26020,36 @@
"node": ">=0.10.0"
}
},
+ "node_modules/default-browser": {
+ "version": "5.5.1",
+ "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.1.tgz",
+ "integrity": "sha512-m1pAzaJgZ/gssEqlOhJkPJp8Xly7QyW6xcrkUa2KKcDeDSEMP7X8xipU3snUcfisTQx0w1AGae+9UtJSfVnXGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "bundle-name": "^4.1.0",
+ "default-browser-id": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/default-browser-id": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz",
+ "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/defaults": {
"version": "1.0.4",
"dev": true,
@@ -25108,6 +26483,16 @@
"is-arrayish": "^0.2.1"
}
},
+ "node_modules/error-stack-parser-es": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-1.0.5.tgz",
+ "integrity": "sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
"node_modules/es-abstract": {
"version": "1.24.2",
"dev": true,
@@ -26402,6 +27787,20 @@
"version": "1.0.0",
"license": "ISC"
},
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
"node_modules/function-bind": {
"version": "1.1.2",
"license": "MIT",
@@ -26930,6 +28329,54 @@
"uglify-js": "^3.1.4"
}
},
+ "node_modules/happy-dom": {
+ "version": "20.14.3",
+ "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-20.14.3.tgz",
+ "integrity": "sha512-0KMb/Eh8rsd+aMNkOk5h8LkAjo9Na1aksnEGmsuZf+GXl6UkAdIi0VbUHU7d59lXhNmawODgwwuCMiZpCxwwCw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "@types/node": ">=20.0.0",
+ "@types/whatwg-mimetype": "^3.0.2",
+ "@types/ws": "^8.18.1",
+ "buffer-image-size": "^0.6.4",
+ "entities": "^7.0.1",
+ "whatwg-mimetype": "^3.0.0",
+ "ws": "^8.21.0"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/happy-dom/node_modules/entities": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz",
+ "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "optional": true,
+ "peer": true,
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/happy-dom/node_modules/whatwg-mimetype": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz",
+ "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/hard-rejection": {
"version": "2.1.0",
"dev": true,
@@ -27826,6 +29273,54 @@
"node": ">=0.10.0"
}
},
+ "node_modules/is-in-ssh": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-in-ssh/-/is-in-ssh-1.0.0.tgz",
+ "integrity": "sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-inside-container": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz",
+ "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-docker": "^3.0.0"
+ },
+ "bin": {
+ "is-inside-container": "cli.js"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-inside-container/node_modules/is-docker": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz",
+ "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "is-docker": "cli.js"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/is-interactive": {
"version": "1.0.0",
"dev": true,
@@ -29300,7 +30795,9 @@
}
},
"node_modules/lightningcss": {
- "version": "1.32.0",
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz",
+ "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==",
"dev": true,
"license": "MPL-2.0",
"dependencies": {
@@ -29314,21 +30811,177 @@
"url": "https://opencollective.com/parcel"
},
"optionalDependencies": {
- "lightningcss-android-arm64": "1.32.0",
- "lightningcss-darwin-arm64": "1.32.0",
- "lightningcss-darwin-x64": "1.32.0",
- "lightningcss-freebsd-x64": "1.32.0",
- "lightningcss-linux-arm-gnueabihf": "1.32.0",
- "lightningcss-linux-arm64-gnu": "1.32.0",
- "lightningcss-linux-arm64-musl": "1.32.0",
- "lightningcss-linux-x64-gnu": "1.32.0",
- "lightningcss-linux-x64-musl": "1.32.0",
- "lightningcss-win32-arm64-msvc": "1.32.0",
- "lightningcss-win32-x64-msvc": "1.32.0"
+ "lightningcss-android-arm64": "1.33.0",
+ "lightningcss-darwin-arm64": "1.33.0",
+ "lightningcss-darwin-x64": "1.33.0",
+ "lightningcss-freebsd-x64": "1.33.0",
+ "lightningcss-linux-arm-gnueabihf": "1.33.0",
+ "lightningcss-linux-arm64-gnu": "1.33.0",
+ "lightningcss-linux-arm64-musl": "1.33.0",
+ "lightningcss-linux-x64-gnu": "1.33.0",
+ "lightningcss-linux-x64-musl": "1.33.0",
+ "lightningcss-win32-arm64-msvc": "1.33.0",
+ "lightningcss-win32-x64-msvc": "1.33.0"
+ }
+ },
+ "node_modules/lightningcss-android-arm64": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz",
+ "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-darwin-arm64": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz",
+ "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-darwin-x64": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz",
+ "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-freebsd-x64": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz",
+ "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm-gnueabihf": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz",
+ "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-gnu": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz",
+ "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-musl": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz",
+ "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
}
},
"node_modules/lightningcss-linux-x64-gnu": {
- "version": "1.32.0",
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz",
+ "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==",
"cpu": [
"x64"
],
@@ -29348,7 +31001,9 @@
}
},
"node_modules/lightningcss-linux-x64-musl": {
- "version": "1.32.0",
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz",
+ "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==",
"cpu": [
"x64"
],
@@ -29367,6 +31022,50 @@
"url": "https://opencollective.com/parcel"
}
},
+ "node_modules/lightningcss-win32-arm64-msvc": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz",
+ "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-x64-msvc": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz",
+ "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
"node_modules/lines-and-columns": {
"version": "2.0.4",
"dev": true,
@@ -29535,7 +31234,6 @@
},
"node_modules/magic-string": {
"version": "0.30.21",
- "dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.5"
@@ -29753,6 +31451,15 @@
"tslib": "2"
}
},
+ "node_modules/memorystream": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
+ "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.10.0"
+ }
+ },
"node_modules/meow": {
"version": "8.1.2",
"dev": true,
@@ -30159,6 +31866,16 @@
"node": ">=4"
}
},
+ "node_modules/mrmime": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz",
+ "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/ms": {
"version": "2.1.3",
"license": "MIT"
@@ -30241,7 +31958,9 @@
}
},
"node_modules/nanoid": {
- "version": "3.3.12",
+ "version": "3.3.18",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz",
+ "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==",
"funding": [
{
"type": "github",
@@ -31115,6 +32834,132 @@
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
+ "node_modules/npm-run-all2": {
+ "version": "9.0.3",
+ "resolved": "https://registry.npmjs.org/npm-run-all2/-/npm-run-all2-9.0.3.tgz",
+ "integrity": "sha512-BQAEdU1PtYc48qYRdghW2BVTQT3VqWCoFQmO87NlM1h1PYwMCKQpUWaNyB20V26caNzFsXQDfyOdznLlHCih6g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^7.0.0",
+ "cross-spawn": "^7.0.6",
+ "memorystream": "^0.3.1",
+ "picomatch": "^4.0.2",
+ "pidtree": "^1.0.0",
+ "read-package-json-fast": "^6.0.0",
+ "shell-quote": "^1.8.4",
+ "which": "^7.0.0"
+ },
+ "bin": {
+ "npm-run-all": "bin/npm-run-all/index.js",
+ "npm-run-all2": "bin/npm-run-all/index.js",
+ "run-p": "bin/run-p/index.js",
+ "run-s": "bin/run-s/index.js"
+ },
+ "engines": {
+ "node": "^22.22.2 || ^24.15.0 || >=26.0.0",
+ "npm": ">= 10"
+ }
+ },
+ "node_modules/npm-run-all2/node_modules/ansi-styles": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-7.0.0.tgz",
+ "integrity": "sha512-kKvt3m4uwzqL0wlkPd09CmljPJGOZZ4D0fP65sqFSvPkMRKhNi+74MgIJ5QxE6SxqB4t4KyUFGg8+n5zjo6hew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=22"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/npm-run-all2/node_modules/isexe": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz",
+ "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/npm-run-all2/node_modules/json-parse-even-better-errors": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-6.0.0.tgz",
+ "integrity": "sha512-2/8adwnK1/+Fdjyts4r6wSpfANWw8zdNhU9U/Llk59c6O+DjSisPWPykwoL8gZmocP9Dy64S7oie2g+Mia123A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^22.22.2 || ^24.15.0 || >=26.0.0"
+ }
+ },
+ "node_modules/npm-run-all2/node_modules/npm-normalize-package-bin": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-6.0.0.tgz",
+ "integrity": "sha512-tdt4aFn9QamlhdN3HV2D2ccpBwO5/fyjjbXUxYA6uBjyekMZcZvDq0aSj9t5Jo+tih6AYFnt/cuIRn9013e0Uw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^22.22.2 || ^24.15.0 || >=26.0.0"
+ }
+ },
+ "node_modules/npm-run-all2/node_modules/picomatch": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz",
+ "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/npm-run-all2/node_modules/read-package-json-fast": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-6.0.0.tgz",
+ "integrity": "sha512-PNaGjoCnw9DBA2Kl8D+8po957z778q/HOPuY2u3Bkw/JO3eC8MDx7jn/PgMtSgpcBbs+6UOjDbwReGpXmRvs0g==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "json-parse-even-better-errors": "^6.0.0",
+ "npm-normalize-package-bin": "^6.0.0"
+ },
+ "engines": {
+ "node": "^22.22.2 || ^24.15.0 || >=26.0.0"
+ }
+ },
+ "node_modules/npm-run-all2/node_modules/shell-quote": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.10.0.tgz",
+ "integrity": "sha512-w1aiOKwKuRgtwAReIIj89puqg+I7GvX4IbLrvmhXbzQsj1+Zwi4VO3+fa6ZF91TWSjIxoEkKnMeHcLEODK5ZXA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/npm-run-all2/node_modules/which": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/which/-/which-7.0.0.tgz",
+ "integrity": "sha512-RancgH2dmbLdHl6LRhEqvklWMgl/Hdnun0Y90KhBOLkMefg8Qa7/Zel8Sm+8HEcP6DEjzsWzpkuBQEZok58isA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^4.0.0"
+ },
+ "bin": {
+ "node-which": "bin/which.js"
+ },
+ "engines": {
+ "node": "^22.22.2 || ^24.15.0 || >=26.0.0"
+ }
+ },
"node_modules/npm-run-path": {
"version": "4.0.1",
"dev": true,
@@ -31428,6 +33273,13 @@
"node": ">=12.20.0"
}
},
+ "node_modules/ohash": {
+ "version": "2.0.12",
+ "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.12.tgz",
+ "integrity": "sha512-65S/5gk9YSsaRjcyf7Nfa6h/d3E8/1gslpXfI4W7Dxn/oap8IKRuNT5VXkLQ1YFKIEg4apRY4Pj6aiwFzrDdmw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/oidc-provider": {
"version": "9.8.3",
"license": "MIT",
@@ -32151,6 +34003,13 @@
"through": "~2.3"
}
},
+ "node_modules/perfect-debounce": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-2.1.0.tgz",
+ "integrity": "sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/picocolors": {
"version": "1.1.1",
"license": "ISC"
@@ -32166,6 +34025,19 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
+ "node_modules/pidtree": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-1.0.0.tgz",
+ "integrity": "sha512-avfAvjB9Dd0wdj3rjJX//yS+G79OO0KrS5pJHFJENjYGX6N4SMgEDBBI/yFy0lloOYSaC6XQxzpOAMPfSYFV/Q==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "pidtree": "bin/pidtree.js"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/pify": {
"version": "5.0.0",
"dev": true,
@@ -32245,8 +34117,9 @@
}
},
"node_modules/postcss": {
- "version": "8.5.15",
- "dev": true,
+ "version": "8.5.28",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz",
+ "integrity": "sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==",
"funding": [
{
"type": "opencollective",
@@ -32263,7 +34136,7 @@
],
"license": "MIT",
"dependencies": {
- "nanoid": "^3.3.12",
+ "nanoid": "^3.3.18",
"picocolors": "^1.1.1",
"source-map-js": "^1.2.1"
},
@@ -32271,6 +34144,19 @@
"node": "^10 || ^12 || >=14"
}
},
+ "node_modules/powershell-utils": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/powershell-utils/-/powershell-utils-0.2.1.tgz",
+ "integrity": "sha512-C+y9x90UElAddDZmV4qOx9W53B61PO7cIqWz2dQsWlwswuq4mr8NEwytdGKboYbQlGZ3awrkTeNvcZiZNHnQ8A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/prelude-ls": {
"version": "1.2.1",
"license": "MIT",
@@ -34049,6 +35935,159 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
+ "node_modules/rolldown/node_modules/@rolldown/binding-android-arm64": {
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.17.tgz",
+ "integrity": "sha512-s70pVGhw4zqGeFnXWvAzJDlvxhlRollagdCCKRgOsgUOH3N1l0LIxf83AtGzmb5SiVM4Hjl5HyarMRfdfj3DaQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/rolldown/node_modules/@rolldown/binding-darwin-arm64": {
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.17.tgz",
+ "integrity": "sha512-4ksWc9n0mhlZpZ9PMZgTGjeOPRu8MB1Z3Tz0Mo02eWfWCHMW1zN82Qz/pL/rC+yQa+8ZnutMF0JjJe7PjwasYw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/rolldown/node_modules/@rolldown/binding-darwin-x64": {
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.17.tgz",
+ "integrity": "sha512-SUSDOI6WwUVNcWxd02QEBjLdY1VPHvlEkw6T/8nYG322iYWCTxRb1vzk4E+mWWYehTp7ERibq54LSJGjmouOsw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/rolldown/node_modules/@rolldown/binding-freebsd-x64": {
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.17.tgz",
+ "integrity": "sha512-hwnz3nw9dbJ05EDO/PvcjaaewqqDy7Y1rn1UO81l8iIK1GjenME75dl16ajbvSSMfv66WXSRCYKIqfgq2KCfxw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/rolldown/node_modules/@rolldown/binding-linux-arm-gnueabihf": {
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.17.tgz",
+ "integrity": "sha512-IS+W7epTcwANmFSQFrS1SivEXHtl1JtuQA9wlxrZTcNi6mx+FDOYrakGevvvTwgj2JvWiK8B29/qD9BELZPyXQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/rolldown/node_modules/@rolldown/binding-linux-arm64-gnu": {
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.17.tgz",
+ "integrity": "sha512-e6usGaHKW5BMNZOymS1UcEYGowQMWcgZ71Z17Sl/h2+ZziNJ1a9n3Zvcz6LdRyIW5572wBCTH/Z+bKuZouGk9Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/rolldown/node_modules/@rolldown/binding-linux-arm64-musl": {
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.17.tgz",
+ "integrity": "sha512-b/CgbwAJpmrRLp02RPfhbudf5tZnN9nsPWK82znefso832etkem8H7FSZwxrOI9djcdTP7U6YfNhbRnh7djErg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/rolldown/node_modules/@rolldown/binding-linux-ppc64-gnu": {
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.17.tgz",
+ "integrity": "sha512-4EII1iNGRUN5WwGbF/kOh/EIkoDN9HsupgLQoXfY+D1oyJm7/F4t5PYU5n8SWZgG0FEwakyM8pGgwcBYruGTlA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/rolldown/node_modules/@rolldown/binding-linux-s390x-gnu": {
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.17.tgz",
+ "integrity": "sha512-AH8oq3XqQo4IibpVXvPeLDI5pzkpYn0WiZAfT05kFzoJ6tQNzwRdDYQ45M8I/gslbodRZwW8uxLhbSBbkv96rA==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
"node_modules/rolldown/node_modules/@rolldown/binding-linux-x64-gnu": {
"version": "1.0.0-rc.17",
"cpu": [
@@ -34064,6 +36103,76 @@
"node": "^20.19.0 || >=22.12.0"
}
},
+ "node_modules/rolldown/node_modules/@rolldown/binding-openharmony-arm64": {
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.17.tgz",
+ "integrity": "sha512-0ag/hEgXOwgw4t8QyQvUCxvEg+V0KBcA6YuOx9g0r02MprutRF5dyljgm3EmR02O292UX7UeS6HzWHAl6KgyhA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/rolldown/node_modules/@rolldown/binding-wasm32-wasi": {
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.17.tgz",
+ "integrity": "sha512-LEXei6vo0E5wTGwpkJ4KoT3OZJRnglwldt5ziLzOlc6qqb55z4tWNq2A+PFqCJuvWWdP53CVhG1Z9NtToDPJrA==",
+ "cpu": [
+ "wasm32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/core": "1.10.0",
+ "@emnapi/runtime": "1.10.0",
+ "@napi-rs/wasm-runtime": "^1.1.4"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/rolldown/node_modules/@rolldown/binding-win32-arm64-msvc": {
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.17.tgz",
+ "integrity": "sha512-gUmyzBl3SPMa6hrqFUth9sVfcLBlYsbMzBx5PlexMroZStgzGqlZ26pYG89rBb45Mnia+oil6YAIFeEWGWhoZA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/rolldown/node_modules/@rolldown/binding-win32-x64-msvc": {
+ "version": "1.0.0-rc.17",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.17.tgz",
+ "integrity": "sha512-3hkiolcUAvPB9FLb3UZdfjVVNWherN1f/skkGWJP/fgSQhYUZpSIRr0/I8ZK9TkF3F7kxvJAk0+IcKvPHk9qQg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
"node_modules/rolldown/node_modules/@rolldown/pluginutils": {
"version": "1.0.0-rc.17",
"dev": true,
@@ -34117,6 +36226,19 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/run-applescript": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz",
+ "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/run-async": {
"version": "2.4.1",
"dev": true,
@@ -34852,6 +36974,21 @@
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
+ "node_modules/sirv": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz",
+ "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@polka/url": "^1.0.0-next.24",
+ "mrmime": "^2.0.0",
+ "totalist": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/sisteransi": {
"version": "1.0.5",
"license": "MIT"
@@ -34929,6 +37066,10 @@
"resolved": "dev/solid-react-vite-app",
"link": true
},
+ "node_modules/solid-vue-vite-app": {
+ "resolved": "dev/solid-vue-vite-app",
+ "link": true
+ },
"node_modules/sorcery": {
"version": "0.11.1",
"dev": true,
@@ -36280,6 +38421,16 @@
"version": "2.0.2",
"license": "MIT"
},
+ "node_modules/totalist": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
+ "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/tough-cookie": {
"version": "5.1.2",
"dev": true,
@@ -36981,7 +39132,7 @@
},
"node_modules/typescript": {
"version": "5.9.3",
- "dev": true,
+ "devOptional": true,
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
@@ -37377,6 +39528,36 @@
"node": ">= 0.8"
}
},
+ "node_modules/unplugin-utils": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/unplugin-utils/-/unplugin-utils-0.3.2.tgz",
+ "integrity": "sha512-xVToRh2CTmLk2HnEG7ac4rl1MJTT3RFkpS8B++/SnB0kXvuaavD+n3m/vrzyWQOdJNSZQACnbz01pnppbwV5BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pathe": "^2.0.3",
+ "picomatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sxzz"
+ }
+ },
+ "node_modules/unplugin-utils/node_modules/picomatch": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz",
+ "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
"node_modules/unrs-resolver": {
"version": "1.12.2",
"dev": true,
@@ -37632,6 +39813,36 @@
}
}
},
+ "node_modules/vite-dev-rpc": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/vite-dev-rpc/-/vite-dev-rpc-2.0.0.tgz",
+ "integrity": "sha512-yKwbTwdHKSD2k/aGqyWpPHepo45OQc8lH3/6IfT4ZqeKE26ooKvi4WIEKzqWav8v+9Is8u1k8q54hvOmqASazA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "birpc": "^4.0.0",
+ "vite-hot-client": "^2.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "vite": "^2.9.0 || ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.1 || ^7.0.0-0 || ^8.0.0"
+ }
+ },
+ "node_modules/vite-hot-client": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/vite-hot-client/-/vite-hot-client-2.2.0.tgz",
+ "integrity": "sha512-76Zs9zrHbH7M7wqeyooGQKdX+yg0pQ0xuQ1PbFp4z5a0Lzn2e5IPFoCswnmqZ4GiwqB4Jo3WcDAMO9jARTJl8w==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "vite": "^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 || ^8.0.0"
+ }
+ },
"node_modules/vite-node": {
"version": "3.2.4",
"dev": true,
@@ -37687,6 +39898,114 @@
}
}
},
+ "node_modules/vite-plugin-inspect": {
+ "version": "11.4.1",
+ "resolved": "https://registry.npmjs.org/vite-plugin-inspect/-/vite-plugin-inspect-11.4.1.tgz",
+ "integrity": "sha512-ShOFe2PURXGvRS5OrgmOLZOCwDTD7dEBVt0tMpFPKb9AsvqXKCRGM8QgKrUbRbJYFXScHvDPpGRd28rYidC0tA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansis": "^4.3.0",
+ "error-stack-parser-es": "^1.0.5",
+ "obug": "^2.1.1",
+ "ohash": "^2.0.11",
+ "open": "^11.0.0",
+ "perfect-debounce": "^2.1.0",
+ "sirv": "^3.0.2",
+ "unplugin-utils": "^0.3.1",
+ "vite-dev-rpc": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "vite": "^6.0.0 || ^7.0.0-0 || ^8.0.0-0"
+ },
+ "peerDependenciesMeta": {
+ "@nuxt/kit": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite-plugin-inspect/node_modules/define-lazy-prop": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz",
+ "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/vite-plugin-inspect/node_modules/open": {
+ "version": "11.0.2",
+ "resolved": "https://registry.npmjs.org/open/-/open-11.0.2.tgz",
+ "integrity": "sha512-RWqF+pBSkqecEvCKOn8QYhaNdRMJDZRIrlS/7rTDdLHaPcfXGCZ/h8zb413NfvdeAV0MR7T1yJcA34/q+CSm1Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "default-browser": "^5.5.1",
+ "define-lazy-prop": "^3.0.0",
+ "is-in-ssh": "^1.0.0",
+ "is-inside-container": "^1.0.0",
+ "powershell-utils": "^0.2.1",
+ "wsl-utils": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/vite-plugin-vue-devtools": {
+ "version": "8.2.1",
+ "resolved": "https://registry.npmjs.org/vite-plugin-vue-devtools/-/vite-plugin-vue-devtools-8.2.1.tgz",
+ "integrity": "sha512-5JLxXWWCo5lJMw16/xVeNvJ8k2zLwZPf1vITLzya/2IePrCBeGe/p/iAokgXHZpEi39fcYtPXmO8SaKeXmqCAA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/devtools-core": "^8.2.1",
+ "@vue/devtools-kit": "^8.2.1",
+ "@vue/devtools-shared": "^8.2.1",
+ "sirv": "^3.0.2",
+ "vite-plugin-inspect": "^11.3.3",
+ "vite-plugin-vue-inspector": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=v14.21.3"
+ },
+ "peerDependencies": {
+ "vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/vite-plugin-vue-inspector": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/vite-plugin-vue-inspector/-/vite-plugin-vue-inspector-6.0.0.tgz",
+ "integrity": "sha512-OpyITJLgZNibxlrik1EmRtvXHDjLRxNPsWkGFTERZs2LgMEdG4W0WoFt5GIgp3a3jRou+eJR8U1zOBk/XQgEbw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.23.0",
+ "@babel/plugin-proposal-decorators": "^7.23.0",
+ "@babel/plugin-syntax-import-attributes": "^7.22.5",
+ "@babel/plugin-syntax-import-meta": "^7.10.4",
+ "@babel/plugin-transform-typescript": "^7.22.15",
+ "@vue/babel-plugin-jsx": "^1.1.5",
+ "@vue/compiler-dom": "^3.3.4",
+ "kolorist": "^1.8.0",
+ "magic-string": "^0.30.4"
+ },
+ "peerDependencies": {
+ "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
"node_modules/vite/node_modules/@esbuild/linux-x64": {
"version": "0.25.12",
"cpu": [
@@ -37877,6 +40196,34 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/vscode-uri": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.2.0.tgz",
+ "integrity": "sha512-m2gXo3bn0G1kT9InzMf07fTbqMbGtyckj3bH5ktLO+1Ssv+yiATZ4dhwaQv9UZWxJh6E9IFGnQyjgWVDWVBDrg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/vue": {
+ "version": "3.5.43",
+ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.43.tgz",
+ "integrity": "sha512-o5qZoksdnjIKvW1srZ3ab7pcDNYAerBjRe54D0LBLfRdCYFrSgBHVXokMas35czQc0//lmx4/tuY4ZNQ+Rf2Ng==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.43",
+ "@vue/compiler-sfc": "3.5.43",
+ "@vue/runtime-dom": "3.5.43",
+ "@vue/server-renderer": "3.5.43",
+ "@vue/shared": "3.5.43"
+ },
+ "peerDependencies": {
+ "typescript": "*"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
"node_modules/vue-template-compiler": {
"version": "2.7.16",
"dev": true,
@@ -38326,7 +40673,9 @@
}
},
"node_modules/ws": {
- "version": "8.20.0",
+ "version": "8.21.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.3.tgz",
+ "integrity": "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
@@ -38344,6 +40693,52 @@
}
}
},
+ "node_modules/wsl-utils": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-1.0.0.tgz",
+ "integrity": "sha512-Hl0ZOAs672vg+06kfujwRhoS6/jehvULrlFkuF2dRu6pHgA8U06h3xqNIqNNU1LTXPcedxByAR4GS6pwQK0mgA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-wsl": "^3.1.0",
+ "powershell-utils": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/wsl-utils/node_modules/is-wsl": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz",
+ "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-inside-container": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/wsl-utils/node_modules/powershell-utils": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/powershell-utils/-/powershell-utils-0.1.0.tgz",
+ "integrity": "sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/xlsx": {
"version": "0.8.8",
"dev": true,
@@ -39813,6 +42208,26 @@
"uuid": "dist/bin/uuid"
}
},
+ "packages/vue": {
+ "name": "@ldo/vue",
+ "version": "1.0.0-alpha.50",
+ "license": "MIT",
+ "dependencies": {
+ "@ldo/connected": "^1.0.0-alpha.50",
+ "@ldo/jsonld-dataset-proxy": "^1.0.0-alpha.50",
+ "@ldo/ldo": "^1.0.0-alpha.50",
+ "@ldo/rdf-utils": "^1.0.0-alpha.50"
+ },
+ "devDependencies": {
+ "@ldo/connected-solid": "^1.0.0-alpha.50",
+ "@ldo/test-solid-server": "^1.0.0-alpha.50",
+ "@types/shexj": "^2.1.7",
+ "vue": "^3.5.43"
+ },
+ "peerDependencies": {
+ "vue": "^3.3.0"
+ }
+ },
"packages/wac": {
"extraneous": true
}
diff --git a/packages/connected-solid/src/notifications/Websocket2023NotificationSubscription.ts b/packages/connected-solid/src/notifications/Websocket2023NotificationSubscription.ts
index 22710130..b7ffc5fa 100644
--- a/packages/connected-solid/src/notifications/Websocket2023NotificationSubscription.ts
+++ b/packages/connected-solid/src/notifications/Websocket2023NotificationSubscription.ts
@@ -22,7 +22,7 @@ const CHANNEL_TYPE =
/**
* @internal
- * An implementation of the Websocket2023 notifiction spec
+ * An implementation of the Websocket2023 notification spec
*/
export class Websocket2023NotificationSubscription extends NotificationSubscription<
SolidConnectedPlugin,
@@ -106,7 +106,10 @@ export class Websocket2023NotificationSubscription extends NotificationSubscript
this.socket.onerror = (err) => {
this.onNotificationError(
- new UnexpectedResourceError(this.resource, err.error),
+ new UnexpectedResourceError(
+ this.resource,
+ err.error ?? new Error("WebSocket error"),
+ ),
);
};
return;
diff --git a/packages/connected/src/linkTraversal/ResourceLinkQuery.ts b/packages/connected/src/linkTraversal/ResourceLinkQuery.ts
index 5567b610..bbdf96b6 100644
--- a/packages/connected/src/linkTraversal/ResourceLinkQuery.ts
+++ b/packages/connected/src/linkTraversal/ResourceLinkQuery.ts
@@ -15,7 +15,7 @@ import type { nodeEventListener } from "@ldo/subscribable-dataset";
import type { Quad } from "@rdfjs/types";
/**
- * Represents a query over multiple datasources and constituting muliple
+ * Represents a query over multiple datasources and constituting multiple
* resources.
*
* @example
@@ -36,7 +36,7 @@ import type { Quad } from "@rdfjs/types";
* },
* }
* );
- * // Susbscribe to this link query, automaticically updating the dataset when
+ * // Subscribe to this link query, automatically updating the dataset when
* // something from the link query is changed.
* await linkQuery.subscribe();
* ```
@@ -102,7 +102,7 @@ export class ResourceLinkQuery<
* },
* }
* );
- * // Susbscribe to this link query, automaticically updating the dataset when
+ * // Subscribe to this link query, automatically updating the dataset when
* // something from the link query is changed.
* const result = await linkQuery.read();
* console.log(result.name);
@@ -149,7 +149,7 @@ export class ResourceLinkQuery<
* },
* }
* );
- * // Susbscribe to this link query, automaticically updating the dataset when
+ * // Subscribe to this link query, automatically updating the dataset when
* // something from the link query is changed.
* const unsubscribeId = await linkQuery.subscribe();
*
diff --git a/packages/connected/src/types/IConnectedLdoDataset.ts b/packages/connected/src/types/IConnectedLdoDataset.ts
index b4e545c5..d904084a 100644
--- a/packages/connected/src/types/IConnectedLdoDataset.ts
+++ b/packages/connected/src/types/IConnectedLdoDataset.ts
@@ -3,6 +3,7 @@ import type { LdoBase, LdoDataset, ShapeType } from "@ldo/ldo";
import type { ConnectedPlugin } from "./ConnectedPlugin";
import type { InvalidIdentifierResource } from "../InvalidIdentifierResource";
import type { IConnectedLdoBuilder } from "./IConnectedLdoBuilder";
+import type { ConnectedLdoTransactionDataset } from "../ConnectedLdoTransactionDataset";
export type ReturnTypeFromArgs = Func extends (
arg: Arg,
@@ -54,7 +55,7 @@ export type GetResourceReturnType<
export interface IConnectedLdoDataset
extends LdoDataset {
/**
- * Retireves a representation of a Resource at the given URI. This resource
+ * Retrieves a representation of a Resource at the given URI. This resource
* represents the current state of the resource: whether it is currently
* fetched or in the process of fetching as well as some information about it.
*
@@ -80,7 +81,7 @@ export interface IConnectedLdoDataset
): GetResourceReturnType;
/**
- * Retireves a representation of all Resources referenced by this dataset
+ * Retrieves a representation of all Resources referenced by this dataset
* This does not necessarily mean that it's been fetched (use the
* `getFetchedResources` method for that). It simply means that at one point
* it was referenced.
@@ -95,7 +96,7 @@ export interface IConnectedLdoDataset
getResources(): Plugins[number]["types"]["resource"][];
/**
- * Retireves a representation of all Resources that have been fetched.
+ * Retrieves a representation of all Resources that have been fetched.
*
* @returns a Resource array
*
@@ -152,7 +153,7 @@ export interface IConnectedLdoDataset
forgetAllResources(): void;
/**
- * Sets conetext for a specific plugin
+ * Sets context for a specific plugin
*
* @param pluginName - the name of the plugin
* @param context - the context for this specific plugin
@@ -168,4 +169,6 @@ export interface IConnectedLdoDataset
usingType(
shapeType: ShapeType,
): IConnectedLdoBuilder;
+
+ startTransaction(): ConnectedLdoTransactionDataset;
}
diff --git a/packages/react/src/methods/useLinkQuery.ts b/packages/react/src/methods/useLinkQuery.ts
index 1accb785..75811c5b 100644
--- a/packages/react/src/methods/useLinkQuery.ts
+++ b/packages/react/src/methods/useLinkQuery.ts
@@ -14,7 +14,7 @@ import { useTrackingProxy } from "../util/useTrackingProxy";
/**
* @internal
*
- * Creates a useMatchSubject function.
+ * Creates a useLinkQuery function.
*/
export function createUseLinkQuery(
dataset: ConnectedLdoDataset,
diff --git a/packages/react/src/methods/useResource.ts b/packages/react/src/methods/useResource.ts
index d17420d4..ad74d9c4 100644
--- a/packages/react/src/methods/useResource.ts
+++ b/packages/react/src/methods/useResource.ts
@@ -57,7 +57,7 @@ export function createUseResource(
const resource = useMemo(() => {
if (uri) {
const resource = dataset.getResource(uri);
- // Run read operations if necissary
+ // Run read operations if necessary
if (!options?.suppressInitialRead) {
if (options?.reloadOnMount) {
resource.read();
@@ -93,7 +93,7 @@ export function createUseResource(
// Callback function to force the react dom to reload.
const forceReload = useCallback(
- // Wrap the resource in a proxy so it's techically a different object
+ // Wrap the resource in a proxy so it's technically a different object
() => {
if (resource) setResourceRepresentation(new Proxy(resource, {}));
},
diff --git a/packages/svelte/src/methods/useLdo.ts b/packages/svelte/src/methods/useLdo.ts
index ea9ca689..5080e1f7 100644
--- a/packages/svelte/src/methods/useLdo.ts
+++ b/packages/svelte/src/methods/useLdo.ts
@@ -17,7 +17,7 @@ export interface UseLdoMethods {
*/
dataset: ConnectedLdoDataset;
/**
- * Retireves a representation of a Resource at the given URI. This resource
+ * Retrieves a representation of a Resource at the given URI. This resource
* represents the current state of the resource: whether it is currently
* fetched or in the process of fetching as well as some information about it.
*
@@ -29,7 +29,7 @@ export interface UseLdoMethods {
*/
getResource: ConnectedLdoDataset["getResource"];
/**
- * Sets conetext for a specific plugin
+ * Sets context for a specific plugin
*
* @param pluginName - the name of the plugin
* @param context - the context for this specific plugin
@@ -66,7 +66,7 @@ export interface UseLdoMethods {
...additionalResources: Plugins[number]["types"]["resource"][]
): Type;
/**
- * Commits the data of a writable Linke Data Object back to the remote.
+ * Commits the data of a writable Linked Data Object back to the remote.
*/
commitData(
input: LdoBase,
diff --git a/packages/svelte/src/methods/useResource.ts b/packages/svelte/src/methods/useResource.ts
index c50b4714..96344c7b 100644
--- a/packages/svelte/src/methods/useResource.ts
+++ b/packages/svelte/src/methods/useResource.ts
@@ -55,7 +55,7 @@ export function createUseResource(
if (uri) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
resource = dataset.getResource(uri) as any;
- // Run read operations if necissary
+ // Run read operations if necessary
if (!options?.suppressInitialRead) {
if (options?.reloadOnMount) {
resource!.read();
diff --git a/packages/vue/README.md b/packages/vue/README.md
new file mode 100644
index 00000000..d8038cdd
--- /dev/null
+++ b/packages/vue/README.md
@@ -0,0 +1,128 @@
+# @ldo/vue
+
+`@ldo/vue` provides composables for easily building Linked Data applications using [Vue](https://vuejs.org).
+
+**Note:** If you're building a [Solid](https://solidproject.org) application with Vue, we recommend that you use [@ldo/solid-vue](https://www.npmjs.com/package/@ldo/solid-vue) instead of this package.
+
+## Installation
+
+If you haven't already, [create your Vue project](https://vuejs.org/guide/quick-start.html#creating-a-vue-application).
+
+Navigate into your project's root folder and run the following command:
+
+```sh
+cd my_project
+npx @ldo/cli init
+```
+
+Now install the `@ldo/vue` library:
+
+```sh
+npm i @ldo/vue
+```
+
+Also install a connected plugin of your choice:
+
+```sh
+npm i @ldo/connected-solid @ldo/connected-nextgraph
+```
+
+
+
+Manual Installation
+
+
+If you already have generated ShapeTypes, you may install the `@ldo/ldo` and `@ldo/vue` libraries independently.
+
+```sh
+npm i @ldo/ldo @ldo/vue
+```
+
+Also install the connected plugin of your choice:
+
+```sh
+npm i @ldo/connected-solid @ldo/connected-nextgraph
+```
+
+
+
+## Simple Example
+
+Below is a simple example of @ldo/vue in a real use-case. Assume that a ShapeType was previously generated and placed at `./_ldo/foafProfile.shapeTypes.ts`.
+
+```ts
+// src/ldo.ts
+
+import { createLdoVueMethods } from "@ldo/vue";
+// replace the plugin with the connected plugin(s) of your choice
+import { solidConnectedPlugin } from "@ldo/connected-solid";
+
+// create LDO Vue methods that will be used in the whole app
+export const {
+ dataset,
+ useSubject,
+ useResource,
+ useMatchSubject,
+ useSubscribeToResource,
+ /* export all you need */
+} = createLdoVueMethods([solidConnectedPlugin]);
+
+// At some point, you may want to implement some form of authentication
+// suitable for your connected plugin.
+// In case of Solid plugin, you need to provide authenticated fetch from the current session
+dataset.setContext("solid", { fetch: authFetch });
+// We recommend you just use @ldo/solid-vue instead
+```
+
+```vue
+
+
+
+
+ Name: {{ subject?.name }}
+
+ Friends:
+
+ -
+ {{ friend["@id"] }}
+
+
+
+
+```
+
+## API Details
+
+Vue [composables](https://vuejs.org/guide/reusability/composables.html):
+
+- [useLdo](https://ldo.js.org/latest/api/vue/useLdo/)
+- [useResource](https://ldo.js.org/latest/api/vue/useResource/)
+- [useSubject](https://ldo.js.org/latest/api/vue/useSubject/)
+- [useMatchSubject](https://ldo.js.org/latest/api/vue/useMatchSubject/)
+- [useMatchObject](https://ldo.js.org/latest/api/vue/useMatchObject/)
+- [useSubscribeToResource](https://ldo.js.org/latest/api/vue/useSubscribeToResource/)
+- [useLinkQuery](https://ldo.js.org/latest/api/vue/useLinkQuery/)
+- [useChangeDataset](https://ldo.js.org/latest/api/vue/useChangeDataset/)
+- [useChangeSubject](https://ldo.js.org/latest/api/vue/useChangeSubject/)
+- [useChangeMatchSubject](https://ldo.js.org/latest/api/vue/useChangeMatchSubject/)
+- [useChangeMatchObject](https://ldo.js.org/latest/api/vue/useChangeMatchObject/)
+
+## Sponsorship
+
+This project was made possible by a grant from [NGI0 Commons Fund](https://nlnet.nl/commonsfund/) via nlnet. Learn more on the [NLnet project page](https://nlnet.nl/project/LDO-up/).
+
+[
](https://nlnet.nl/)
+[
](https://nlnet.nl/commonsfund/)
+
+## License
+
+MIT
diff --git a/packages/vue/package.json b/packages/vue/package.json
new file mode 100644
index 00000000..c1f691a8
--- /dev/null
+++ b/packages/vue/package.json
@@ -0,0 +1,58 @@
+{
+ "name": "@ldo/vue",
+ "version": "1.0.0-alpha.50",
+ "description": "A Vue library for LDO",
+ "type": "module",
+ "main": "./dist/index.cjs",
+ "module": "./dist/index.mjs",
+ "types": "./dist/index.d.mts",
+ "exports": {
+ ".": {
+ "import": {
+ "types": "./dist/index.d.mts",
+ "default": "./dist/index.mjs"
+ },
+ "require": {
+ "types": "./dist/index.d.cts",
+ "default": "./dist/index.cjs"
+ }
+ },
+ "./package.json": "./package.json"
+ },
+ "scripts": {
+ "build": "rimraf dist && NODE_OPTIONS=--max-old-space-size=8192 tsdown",
+ "test": "vitest run --coverage"
+ },
+ "keywords": [
+ "ldo",
+ "linked-data-objects",
+ "rdf",
+ "solid-project",
+ "vuejs"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/o-development/ldo.git"
+ },
+ "author": "Jackson Morgan",
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/o-development/ldo/issues"
+ },
+ "homepage": "https://github.com/o-development/ldo/tree/main/packages/vue#readme",
+ "dependencies": {
+ "@ldo/connected": "^1.0.0-alpha.50",
+ "@ldo/jsonld-dataset-proxy": "^1.0.0-alpha.50",
+ "@ldo/ldo": "^1.0.0-alpha.50",
+ "@ldo/rdf-utils": "^1.0.0-alpha.50"
+ },
+ "peerDependencies": {
+ "vue": "^3.3.0"
+ },
+ "devDependencies": {
+ "@ldo/connected-solid": "^1.0.0-alpha.50",
+ "@ldo/test-solid-server": "^1.0.0-alpha.50",
+ "@types/shexj": "^2.1.7",
+ "vue": "^3.5.43"
+ }
+}
diff --git a/packages/vue/src/createLdoVueComposables.ts b/packages/vue/src/createLdoVueComposables.ts
new file mode 100644
index 00000000..7ebeba2b
--- /dev/null
+++ b/packages/vue/src/createLdoVueComposables.ts
@@ -0,0 +1,129 @@
+import {
+ type ConnectedLdoDataset,
+ createConnectedLdoDataset,
+ type ConnectedPlugin,
+} from "@ldo/connected";
+import { inject, provide, type InjectionKey } from "vue";
+import { createUseSubject } from "./methods/useSubject";
+import { createUseMatchObject } from "./methods/useMatchObject";
+import { createUseResource } from "./methods/useResource";
+import { createUseMatchSubject } from "./methods/useMatchSubject";
+import { createUseDataset } from "./methods/useDataset";
+import { createUseLdo } from "./methods/useLdo";
+import { createUseSubscribeToResource } from "./methods/useSubscribeToResource";
+import { createUseLinkQuery } from "./methods/useLinkQuery";
+import { createUseChangeDataset } from "./methods/change/useChangeDataset";
+import { createUseChangeMatchObject } from "./methods/change/useChangeMatchObject";
+import { createUseChangeMatchSubject } from "./methods/change/useChangeMatchSubject";
+
+/**
+ * Create ldo composables for Vue, where the dataset is isolated and provided/injected.
+ *
+ * You have to run `provideDataset()` in the ancestor component to set up the dataset.
+ *
+ * @example
+ * ```ts
+ * // in ldoComposables.ts do
+ *
+ * export const { provideDataset, useDataset, useSubject, ...etc } = createLdoVueComposables(connectedPlugins);
+ * export { provideDataset, useDataset }
+ *
+ * // provide dataset in parent component
+ * provideDataset()
+ *
+ * // use composables in child component
+ * const subjectLdo = useSubject(...subjectProps)
+ * ```
+ */
+export function createLdoVueComposables(
+ plugins: Plugin[],
+) {
+ const datasetInjectionKey: InjectionKey> =
+ Symbol("Dataset Key");
+
+ function provideDataset() {
+ const dataset = createConnectedLdoDataset(plugins);
+ provide(datasetInjectionKey, dataset);
+ return dataset;
+ }
+
+ return {
+ datasetInjectionKey,
+ provideDataset,
+ useDataset: createComposable(
+ datasetInjectionKey,
+ createUseDataset,
+ ),
+ useLdo: createComposable(datasetInjectionKey, createUseLdo),
+ useResource: createComposable(
+ datasetInjectionKey,
+ createUseResource,
+ ),
+ useSubject: createComposable(
+ datasetInjectionKey,
+ createUseSubject,
+ ),
+ useMatchObject: createComposable(
+ datasetInjectionKey,
+ createUseMatchObject,
+ ),
+ useMatchSubject: createComposable(
+ datasetInjectionKey,
+ createUseMatchSubject,
+ ),
+ useSubscribeToResource: createComposable(
+ datasetInjectionKey,
+ createUseSubscribeToResource,
+ ),
+ useLinkQuery: createComposable(
+ datasetInjectionKey,
+ createUseLinkQuery,
+ ),
+ useChangeDataset: createComposable(
+ datasetInjectionKey,
+ createUseChangeDataset,
+ ),
+ useChangeSubject: createComposable(
+ datasetInjectionKey,
+ createUseSubject,
+ ),
+ useChangeMatchObject: createComposable(
+ datasetInjectionKey,
+ createUseChangeMatchObject,
+ ),
+ useChangeMatchSubject: createComposable(
+ datasetInjectionKey,
+ createUseChangeMatchSubject,
+ ),
+ };
+}
+
+/**
+ * @internal
+ *
+ * A method to create the composable with injected dataset
+ */
+const createComposable = <
+ Plugin extends ConnectedPlugin,
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ CreateComposable extends (dataset: ConnectedLdoDataset) => any,
+>(
+ key: InjectionKey>,
+ creator: CreateComposable,
+): ReturnType => {
+ // We return a proxy function matching the exact signature layout of the underlying contract
+ return function wrappedMethod(
+ ...props: Parameters>
+ ): ReturnType> {
+ // inject the dataset
+ const dataset = inject(key);
+ // check that it's actually provided
+ if (!dataset)
+ throw new Error(
+ "Composable must have a dataset provider. Please call provideDataset() in a parent component.",
+ );
+
+ // Create and run the composable with the injected dataset
+ return creator(dataset)(...props);
+ } as ReturnType;
+};
diff --git a/packages/vue/src/createLdoVueMethods.ts b/packages/vue/src/createLdoVueMethods.ts
new file mode 100644
index 00000000..2cdba671
--- /dev/null
+++ b/packages/vue/src/createLdoVueMethods.ts
@@ -0,0 +1,89 @@
+import {
+ createConnectedLdoDataset,
+ type ConnectedPlugin,
+} from "@ldo/connected";
+import { createUseLdo } from "./methods/useLdo";
+import { createUseMatchObject } from "./methods/useMatchObject";
+import { createUseMatchSubject } from "./methods/useMatchSubject";
+import { createUseResource } from "./methods/useResource";
+import { createUseSubject } from "./methods/useSubject";
+import { createUseSubscribeToResource } from "./methods/useSubscribeToResource";
+import { createUseLinkQuery } from "./methods/useLinkQuery";
+import { createUseChangeDataset } from "./methods/change/useChangeDataset";
+import { createUseChangeSubject } from "./methods/change/useChangeSubject";
+import { createUseChangeMatchObject } from "./methods/change/useChangeMatchObject";
+import { createUseChangeMatchSubject } from "./methods/change/useChangeMatchSubject";
+import { createUseDataset } from "./methods/useDataset";
+
+/**
+ * A function that creates all common vue functions given specific plugin.
+ *
+ * @example
+ * `methods.ts`
+ * ```tsx
+ * import { solidConnectedPlugin } from "@ldo/connected-solid";
+ * import { nextGraphConnectedPlugin } from "@ldo/connected-nextgraph";
+ * import { createLdoVueMethods } from "@ldo/vue";
+ *
+ * // Export the results to be used in the reset of the application
+ * export const {
+ * dataset,
+ * useLdo,
+ * useMatchObject,
+ * useMatchSubject,
+ * useResource,
+ * useSubject,
+ * useSubscribeToResource,
+ * useLinkQuery,
+ * useChangeDataset,
+ * useChangeSubject,
+ * useChangeMatchObject,
+ * useChangeMatchSubject,
+ * } = createLdoVueMethods([
+ * solidConnectedPlugin,
+ * nextGraphConnectedPlugin
+ * ]);
+ * ```
+ *
+ * `App.vue`
+ * ```vue
+ *
+ *
+ *
+ *
+ * -
+ * {{ publisher["id"] }}
+ *
+ *
+ *
+ * ```
+ */
+export function createLdoVueMethods(
+ plugins: Plugin[],
+) {
+ const dataset = createConnectedLdoDataset(plugins);
+ dataset.setMaxListeners(1000);
+
+ return {
+ dataset,
+ useDataset: createUseDataset(dataset),
+ useLdo: createUseLdo(dataset),
+ useResource: createUseResource(dataset),
+ useSubject: createUseSubject(dataset),
+ useMatchObject: createUseMatchObject(dataset),
+ useMatchSubject: createUseMatchSubject(dataset),
+ useSubscribeToResource: createUseSubscribeToResource(dataset),
+ useLinkQuery: createUseLinkQuery(dataset),
+ useChangeDataset: createUseChangeDataset(dataset),
+ useChangeSubject: createUseChangeSubject(dataset),
+ useChangeMatchObject: createUseChangeMatchObject(dataset),
+ useChangeMatchSubject: createUseChangeMatchSubject(dataset),
+ };
+}
diff --git a/packages/vue/src/index.ts b/packages/vue/src/index.ts
new file mode 100644
index 00000000..9ed3d07e
--- /dev/null
+++ b/packages/vue/src/index.ts
@@ -0,0 +1,19 @@
+export * from "./createLdoVueMethods";
+export * from "./createLdoVueComposables";
+
+export * from "./methods/useDataset";
+export * from "./methods/useLdo";
+export * from "./methods/useMatchObject";
+export * from "./methods/useMatchSubject";
+export * from "./methods/useResource";
+export * from "./methods/useSubject";
+export * from "./methods/useSubscribeToResource";
+export * from "./methods/useLinkQuery";
+
+// export * from "./methods/change/types";
+export * from "./methods/change/useChangeDataset";
+export * from "./methods/change/useChangeSubject";
+export * from "./methods/change/useChangeMatchObject";
+export * from "./methods/change/useChangeMatchSubject";
+
+export * from "./util/useTrackingProxy";
diff --git a/packages/vue/src/methods/change/useChangeDataset.ts b/packages/vue/src/methods/change/useChangeDataset.ts
new file mode 100644
index 00000000..b08590b5
--- /dev/null
+++ b/packages/vue/src/methods/change/useChangeDataset.ts
@@ -0,0 +1,83 @@
+import type {
+ ConnectedLdoTransactionDataset,
+ ConnectedPlugin,
+ IConnectedLdoDataset,
+} from "@ldo/connected";
+import {
+ type MaybeRefOrGetter,
+ toValue,
+ shallowRef,
+ watch,
+ type Ref,
+} from "vue";
+
+/**
+ * @internal
+ *
+ * Creates a useChangeDataset composable
+ */
+export function createUseChangeDataset(
+ dataset: IConnectedLdoDataset,
+) {
+ /**
+ * Returns a transaction on the dataset that can be modified and committed.
+ *
+ * @example
+ * ```ts
+ * const { transactionDataset, setData, commitData } = useChangeDataset();
+ * // you must populate the dataset with data in order to change it
+ * const resource = useResource(resourceUri);
+ *
+ * // you can do this in a callback, e. g. form update
+ * setData((dataset) => {
+ * // perform operations on the dataset
+ * dataset.deleteMatches(some, match);
+ * dataset.add(quad(subject, predicate, object, graph))
+ * // etc...
+ * });
+ *
+ * // save the data
+ * const result = await results.changeDataset.commitData()
+ *
+ * // check the result for errors
+ * ```
+ */
+ return function useChangeDataset(
+ specificDataset?: MaybeRefOrGetter<
+ IConnectedLdoDataset | undefined
+ >,
+ ) {
+ const transactionDataset = shallowRef<
+ ConnectedLdoTransactionDataset
+ >() as Ref>;
+
+ watch(
+ () => toValue(specificDataset),
+ (newDataset) => {
+ transactionDataset.value = (newDataset ?? dataset).startTransaction();
+ },
+ { deep: false, immediate: true },
+ );
+
+ const setData = (
+ changer: (toChange: ConnectedLdoTransactionDataset) => void,
+ ) => {
+ const subTransaction = transactionDataset.value.startTransaction();
+ changer(subTransaction);
+ subTransaction.commit();
+ };
+
+ const commitData = async () => {
+ const result = await transactionDataset.value.commitToRemote();
+ if (!result.isError) {
+ // Replace with a new transaction from the dataset or specificDataset
+ transactionDataset.value = (
+ toValue(specificDataset) ?? dataset
+ ).startTransaction();
+ }
+ return result;
+ };
+
+ return { transactionDataset, setData, commitData };
+ };
+}
diff --git a/packages/vue/src/methods/change/useChangeMatchObject.ts b/packages/vue/src/methods/change/useChangeMatchObject.ts
new file mode 100644
index 00000000..0eec2a15
--- /dev/null
+++ b/packages/vue/src/methods/change/useChangeMatchObject.ts
@@ -0,0 +1,91 @@
+import type { IConnectedLdoDataset, ConnectedPlugin } from "@ldo/connected";
+import { type LdSet, write, type LdoBase, type ShapeType } from "@ldo/ldo";
+import { computed, toValue, type MaybeRefOrGetter } from "vue";
+import { createUseChangeDataset } from "./useChangeDataset";
+import type { QuadMatch } from "@ldo/rdf-utils";
+import { createProxyInteractOptions } from "@ldo/jsonld-dataset-proxy";
+import {
+ createUseMatchObject,
+ type UseMatchObjectOptions,
+} from "../useMatchObject";
+
+/**
+ * @internal
+ *
+ * Creates a useChangeMatchObject composable
+ */
+export function createUseChangeMatchObject(
+ dataset: IConnectedLdoDataset,
+) {
+ const useChangeDataset = createUseChangeDataset(dataset);
+ const useMatchObject = createUseMatchObject(dataset);
+
+ /**
+ * Returns a reactive list of matched objects that can be modified and committed
+ */
+ return function useChangeMatchObject(
+ shapeType: MaybeRefOrGetter>,
+ subject?: MaybeRefOrGetter,
+ predicate?: MaybeRefOrGetter,
+ graph?: MaybeRefOrGetter,
+ options?: MaybeRefOrGetter>,
+ ) {
+ const resolvedDataset = computed(() => toValue(options)?.dataset);
+
+ const {
+ transactionDataset,
+ setData: setDataset,
+ commitData,
+ } = useChangeDataset(resolvedDataset);
+
+ const transactionDatasetOption = computed(() => ({
+ dataset: transactionDataset.value,
+ }));
+
+ const ldObject = useMatchObject(
+ shapeType,
+ subject,
+ predicate,
+ graph,
+ transactionDatasetOption,
+ );
+
+ const setData = <
+ OtherType extends LdoBase | LdSet | undefined = undefined,
+ >(
+ writeResource: Plugins[number]["types"]["resource"],
+ changer: (
+ toChange: OtherType extends undefined ? LdSet : OtherType,
+ ) => void,
+ otherType?: OtherType,
+ ) => {
+ setDataset((dataset) => {
+ const ldObject = otherType
+ ? write(writeResource.uri).usingCopy(
+ createProxyInteractOptions("dataset", dataset).usingCopy(
+ otherType,
+ )[0],
+ )[0]
+ : dataset
+ .usingType(toValue(shapeType))
+ .write(writeResource.uri)
+ .matchObject(
+ toValue(subject),
+ toValue(predicate),
+ toValue(graph),
+ );
+
+ changer(
+ ldObject as OtherType extends undefined ? LdSet : OtherType,
+ );
+ });
+ };
+
+ return {
+ ldo: ldObject,
+ setData,
+ commitData,
+ transactionDataset,
+ };
+ };
+}
diff --git a/packages/vue/src/methods/change/useChangeMatchSubject.ts b/packages/vue/src/methods/change/useChangeMatchSubject.ts
new file mode 100644
index 00000000..89267ca9
--- /dev/null
+++ b/packages/vue/src/methods/change/useChangeMatchSubject.ts
@@ -0,0 +1,91 @@
+import type { IConnectedLdoDataset, ConnectedPlugin } from "@ldo/connected";
+import { type LdSet, write, type LdoBase, type ShapeType } from "@ldo/ldo";
+import { computed, toValue, type MaybeRefOrGetter } from "vue";
+import { createUseChangeDataset } from "./useChangeDataset";
+import type { QuadMatch } from "@ldo/rdf-utils";
+import { createProxyInteractOptions } from "@ldo/jsonld-dataset-proxy";
+import {
+ createUseMatchSubject,
+ type UseMatchSubjectOptions,
+} from "../useMatchSubject";
+
+/**
+ * @internal
+ *
+ * Creates a useChangeMatchSubject composable
+ */
+export function createUseChangeMatchSubject(
+ dataset: IConnectedLdoDataset,
+) {
+ const useChangeDataset = createUseChangeDataset(dataset);
+ const useMatchSubject = createUseMatchSubject(dataset);
+
+ /**
+ * Returns a reactive list of matched subjects that can be modified and committed
+ */
+ return function useChangeMatchSubject(
+ shapeType: MaybeRefOrGetter>,
+ predicate?: MaybeRefOrGetter,
+ object?: MaybeRefOrGetter,
+ graph?: MaybeRefOrGetter,
+ options?: MaybeRefOrGetter>,
+ ) {
+ const resolvedDataset = computed(() => toValue(options)?.dataset);
+
+ const {
+ transactionDataset,
+ setData: setDataset,
+ commitData,
+ } = useChangeDataset(resolvedDataset);
+
+ const transactionDatasetOption = computed(() => ({
+ dataset: transactionDataset.value,
+ }));
+
+ const ldObject = useMatchSubject(
+ shapeType,
+ predicate,
+ object,
+ graph,
+ transactionDatasetOption,
+ );
+
+ const setData = <
+ OtherType extends LdoBase | LdSet | undefined = undefined,
+ >(
+ writeResource: Plugins[number]["types"]["resource"],
+ changer: (
+ toChange: OtherType extends undefined ? LdSet : OtherType,
+ ) => void,
+ otherType?: OtherType,
+ ) => {
+ setDataset((dataset) => {
+ const ldObject = otherType
+ ? write(writeResource.uri).usingCopy(
+ createProxyInteractOptions("dataset", dataset).usingCopy(
+ otherType,
+ )[0],
+ )[0]
+ : dataset
+ .usingType(toValue(shapeType))
+ .write(writeResource.uri)
+ .matchSubject(
+ toValue(predicate),
+ toValue(object),
+ toValue(graph),
+ );
+
+ changer(
+ ldObject as OtherType extends undefined ? LdSet : OtherType,
+ );
+ });
+ };
+
+ return {
+ ldo: ldObject,
+ setData,
+ commitData,
+ transactionDataset,
+ };
+ };
+}
diff --git a/packages/vue/src/methods/change/useChangeSubject.ts b/packages/vue/src/methods/change/useChangeSubject.ts
new file mode 100644
index 00000000..d42b9f7a
--- /dev/null
+++ b/packages/vue/src/methods/change/useChangeSubject.ts
@@ -0,0 +1,76 @@
+import type { IConnectedLdoDataset, ConnectedPlugin } from "@ldo/connected";
+import { type LdSet, write, type LdoBase, type ShapeType } from "@ldo/ldo";
+import { computed, toValue, type MaybeRefOrGetter } from "vue";
+import { createUseChangeDataset } from "./useChangeDataset";
+import type { SubjectNode } from "@ldo/rdf-utils";
+import { createUseSubject, type UseSubjectOptions } from "../useSubject";
+import { createProxyInteractOptions } from "@ldo/jsonld-dataset-proxy";
+
+/**
+ * @internal
+ *
+ * Creates a useChangeSubject composable.
+ */
+export function createUseChangeSubject(
+ dataset: IConnectedLdoDataset,
+) {
+ const useChangeDataset = createUseChangeDataset(dataset);
+ const useSubject = createUseSubject(dataset);
+
+ /**
+ * Returns a reactive subject that can be modified and committed
+ */
+ return function useChangeSubject(
+ shapeType: MaybeRefOrGetter>,
+ subject: MaybeRefOrGetter,
+ options?: MaybeRefOrGetter>,
+ ) {
+ const resolvedDataset = computed(() => toValue(options)?.dataset);
+
+ const {
+ transactionDataset,
+ setData: setDataset,
+ commitData,
+ } = useChangeDataset(resolvedDataset);
+
+ const subjectTransactionDataset = computed(() => ({
+ dataset: transactionDataset.value,
+ }));
+
+ const ldObject = useSubject(shapeType, subject, subjectTransactionDataset);
+
+ const setData = <
+ OtherType extends LdoBase | LdSet | undefined = undefined,
+ >(
+ writeResource: Plugins[number]["types"]["resource"],
+ changer: (
+ toChange: OtherType extends undefined ? Type : OtherType,
+ ) => void,
+ otherType?: OtherType,
+ ) => {
+ const subjectValue = toValue(subject);
+ if (!subjectValue) return;
+ setDataset((dataset) => {
+ const ldObject = otherType
+ ? write(writeResource.uri).usingCopy(
+ createProxyInteractOptions("dataset", dataset).usingCopy(
+ otherType,
+ )[0],
+ )[0]
+ : dataset
+ .usingType(toValue(shapeType))
+ .write(writeResource.uri)
+ .fromSubject(subjectValue);
+
+ changer(ldObject as OtherType extends undefined ? Type : OtherType);
+ });
+ };
+
+ return {
+ ldo: ldObject,
+ setData,
+ commitData,
+ transactionDataset,
+ };
+ };
+}
diff --git a/packages/vue/src/methods/useDataset.ts b/packages/vue/src/methods/useDataset.ts
new file mode 100644
index 00000000..b643dfad
--- /dev/null
+++ b/packages/vue/src/methods/useDataset.ts
@@ -0,0 +1,17 @@
+import type { IConnectedLdoDataset, ConnectedPlugin } from "@ldo/connected";
+
+/**
+ * @internal
+ *
+ * Creates a useDataset function
+ */
+export function createUseDataset(
+ dataset: IConnectedLdoDataset,
+) {
+ /**
+ * Returns the global dataset for the application
+ */
+ return function useDataset() {
+ return dataset;
+ };
+}
diff --git a/packages/vue/src/methods/useLdo.ts b/packages/vue/src/methods/useLdo.ts
new file mode 100644
index 00000000..81821ee8
--- /dev/null
+++ b/packages/vue/src/methods/useLdo.ts
@@ -0,0 +1,152 @@
+/*
+This is a copy from @ldo/react library.
+It has nothing framework-specific in it.
+It's just a wrapper of ldo methods that looks like a composable.
+*/
+
+import {
+ changeData,
+ type ConnectedLdoDataset,
+ type ConnectedLdoTransactionDataset,
+ type ConnectedPlugin,
+} from "@ldo/connected";
+import { getDataset, type LdoBase, type ShapeType } from "@ldo/ldo";
+import type { SubjectNode } from "@ldo/rdf-utils";
+
+/**
+ * The methods returned by useLdo
+ */
+export interface UseLdoMethods {
+ /**
+ * A ConnectedLdoDataset
+ */
+ dataset: ConnectedLdoDataset;
+ /**
+ * Retrieves a representation of a Resource at the given URI. This resource
+ * represents the current state of the resource: whether it is currently
+ * fetched or in the process of fetching as well as some information about it.
+ *
+ * @param uri - the URI of the resource
+ * @param pluginName - optionally, force this function to choose a specific
+ * plugin to use rather than perform content negotiation.
+ *
+ * @returns a Resource
+ */
+ getResource: ConnectedLdoDataset["getResource"];
+ /**
+ * Sets context for a specific plugin
+ *
+ * @param pluginName - the name of the plugin
+ * @param context - the context for this specific plugin
+ */
+ setContext: ConnectedLdoDataset["setContext"];
+ /**
+ * Gets a linked data object based on the subject
+ */
+ getSubject(
+ shapeType: ShapeType,
+ subject: string | SubjectNode,
+ ): Type;
+ /**
+ * Shorthand for connectedLdoDataset
+ * .usingType(shapeType)
+ * .write(...resources.map((r) => r.uri))
+ * .fromSubject(subject);
+ * @param shapeType - The shapeType to represent the data
+ * @param subject - A subject URI
+ * @param resources - The resources changes to should written to
+ */
+ createData(
+ shapeType: ShapeType,
+ subject: string | SubjectNode,
+ resource: Plugins[number]["types"]["resource"],
+ ...additionalResources: Plugins[number]["types"]["resource"][]
+ ): Type;
+ /**
+ * Returns a writable LinkedDataObject given a linked data object
+ */
+ changeData(
+ input: Type,
+ resource: Plugins[number]["types"]["resource"],
+ ...additionalResources: Plugins[number]["types"]["resource"][]
+ ): Type;
+ /**
+ * Commits the data of a writable Linked Data Object back to the remote.
+ */
+ commitData(
+ input: LdoBase,
+ ): ReturnType["commitToRemote"]>;
+}
+
+/**
+ * @internal
+ * Creates a useLdo composable
+ */
+export function createUseLdo(
+ dataset: ConnectedLdoDataset,
+) {
+ const toReturn = {
+ dataset,
+ /**
+ * Gets a resource
+ */
+ getResource: dataset.getResource.bind(dataset),
+ /**
+ * Set the context
+ */
+ setContext: dataset.setContext.bind(dataset),
+ /**
+ * Returns a Linked Data Object for a subject
+ * @param shapeType The shape type for the data
+ * @param subject Subject Node
+ * @returns A Linked Data Object
+ */
+ getSubject(
+ shapeType: ShapeType,
+ subject: string | SubjectNode,
+ ): Type {
+ return dataset.usingType(shapeType).fromSubject(subject);
+ },
+ /**
+ * Begins tracking changes to eventually commit for a new subject
+ * @param shapeType The shape type that defines the created data
+ * @param subject The RDF subject for a Linked Data Object
+ * @param resources Any number of resources to which this data should be written
+ * @returns A Linked Data Object to modify and commit
+ */
+ createData(
+ shapeType: ShapeType,
+ subject: string | SubjectNode,
+ resource: Plugins[number]["types"]["resource"],
+ ...additionalResources: Plugins[number]["types"]["resource"][]
+ ): Type {
+ return dataset.createData(
+ shapeType,
+ subject,
+ resource,
+ ...additionalResources,
+ );
+ },
+ /**
+ * Begins tracking changes to eventually commit
+ * @param input A linked data object to track changes on
+ * @param resources
+ */
+ changeData: changeData,
+ /**
+ * Commits the transaction to the global dataset, syncing all subscribing
+ * components and Solid Pods
+ */
+ commitData(
+ input: LdoBase,
+ ): ReturnType["commitToRemote"]> {
+ const inputDataset = getDataset(
+ input,
+ ) as ConnectedLdoTransactionDataset;
+ return inputDataset.commitToRemote();
+ },
+ };
+ return function useLdo(): UseLdoMethods {
+ return toReturn;
+ };
+}
diff --git a/packages/vue/src/methods/useLinkQuery.ts b/packages/vue/src/methods/useLinkQuery.ts
new file mode 100644
index 00000000..d024adb3
--- /dev/null
+++ b/packages/vue/src/methods/useLinkQuery.ts
@@ -0,0 +1,67 @@
+import type {
+ IConnectedLdoDataset,
+ ConnectedPlugin,
+ LQInput,
+} from "@ldo/connected";
+import type { LdoBase, ShapeType } from "@ldo/ldo";
+import type { SubjectNode } from "@ldo/rdf-utils";
+import { createUseSubject } from "./useSubject";
+import { type MaybeRefOrGetter, toValue, watch } from "vue";
+
+/**
+ * @internal
+ *
+ * Creates a useLinkQuery composable.
+ */
+export function createUseLinkQuery(
+ dataset: IConnectedLdoDataset,
+) {
+ /**
+ * Runs a LDO link query.
+ * Subscribes to related changes.
+ * Returns the starting point as a reactive Linked Data Object.
+ */
+ return function useLinkQuery<
+ Type extends LdoBase,
+ QueryInput extends LQInput,
+ >(
+ shapeType: MaybeRefOrGetter>,
+ startingResource: MaybeRefOrGetter,
+ startingSubject: MaybeRefOrGetter,
+ linkQuery: MaybeRefOrGetter,
+ ) {
+ watch(
+ [
+ () => toValue(shapeType),
+ () => toValue(startingResource),
+ () => toValue(startingSubject),
+ () => toValue(linkQuery),
+ ],
+ async (
+ [shapeType, startingResourceUri, startingSubjectUri, linkQuery],
+ _,
+ onCleanup,
+ ) => {
+ let finished = false;
+ const resource = dataset.getResource(startingResourceUri);
+ const resourceLinkQuery = dataset
+ .usingType(shapeType)
+ .startLinkQuery(resource, startingSubjectUri, linkQuery);
+
+ await resourceLinkQuery.subscribe();
+ // if already cleaned up, unsubscribe immediately
+ if (finished) {
+ await resourceLinkQuery.unsubscribeAll();
+ }
+
+ onCleanup(async () => {
+ finished = true;
+ await resourceLinkQuery.unsubscribeAll();
+ });
+ },
+ { immediate: true },
+ );
+
+ return createUseSubject(dataset)(shapeType, startingSubject);
+ };
+}
diff --git a/packages/vue/src/methods/useMatchObject.ts b/packages/vue/src/methods/useMatchObject.ts
new file mode 100644
index 00000000..aecd7e79
--- /dev/null
+++ b/packages/vue/src/methods/useMatchObject.ts
@@ -0,0 +1,58 @@
+import type { QuadMatch } from "@ldo/rdf-utils";
+import type { ShapeType, LdoBase, LdSet, LdoBuilder } from "@ldo/ldo";
+import { useTrackingProxy } from "../util/useTrackingProxy";
+import type { ConnectedPlugin, IConnectedLdoDataset } from "@ldo/connected";
+import { computed, toValue, type MaybeRefOrGetter, type Ref } from "vue";
+
+export interface UseMatchObjectOptions {
+ dataset?: IConnectedLdoDataset;
+}
+
+export interface UseMatchObjectComposable {
+ (
+ shapeType: MaybeRefOrGetter>,
+ subject?: MaybeRefOrGetter,
+ predicate?: MaybeRefOrGetter,
+ graph?: MaybeRefOrGetter,
+ options?: MaybeRefOrGetter>,
+ ): Ref>;
+}
+
+/**
+ * @internal
+ *
+ * Creates a useMatchObject composable.
+ */
+export function createUseMatchObject(
+ dataset: IConnectedLdoDataset,
+): UseMatchObjectComposable {
+ /**
+ * Returns a reactive LDO set of matching items.
+ * Triggers a rerender if that data are updated.
+ */
+ return function useMatchObject<
+ Type extends LdoBase,
+ CustomPlugins extends ConnectedPlugin[] = Plugins,
+ >(
+ shapeType: MaybeRefOrGetter>,
+ subject?: MaybeRefOrGetter,
+ predicate?: MaybeRefOrGetter,
+ graph?: MaybeRefOrGetter,
+ options?: MaybeRefOrGetter>,
+ ): Ref> {
+ const createLdo = computed(() => {
+ const subjectValue = toValue(subject);
+ const predicateValue = toValue(predicate);
+ const graphValue = toValue(graph);
+
+ return (builder: LdoBuilder) =>
+ builder.matchObject(subjectValue, predicateValue, graphValue);
+ });
+
+ return useTrackingProxy(
+ shapeType,
+ createLdo,
+ () => toValue(options)?.dataset ?? dataset,
+ );
+ };
+}
diff --git a/packages/vue/src/methods/useMatchSubject.ts b/packages/vue/src/methods/useMatchSubject.ts
new file mode 100644
index 00000000..556eb295
--- /dev/null
+++ b/packages/vue/src/methods/useMatchSubject.ts
@@ -0,0 +1,44 @@
+import type { QuadMatch } from "@ldo/rdf-utils";
+import type { ShapeType, LdoBase, LdSet, LdoBuilder } from "@ldo/ldo";
+import { useTrackingProxy } from "../util/useTrackingProxy";
+import type { ConnectedPlugin, IConnectedLdoDataset } from "@ldo/connected";
+import { computed, toValue, type MaybeRefOrGetter, type Ref } from "vue";
+
+export interface UseMatchSubjectOptions {
+ dataset?: IConnectedLdoDataset;
+}
+
+/**
+ * @internal
+ *
+ * Creates a useMatchSubject composable.
+ */
+export function createUseMatchSubject(
+ dataset: IConnectedLdoDataset,
+) {
+ /**
+ * Returns a reactive LDO set of matching linked data objects.
+ * Triggers a rerender if the data are updated.
+ */
+ return function useMatchSubject(
+ shapeType: MaybeRefOrGetter>,
+ predicate?: MaybeRefOrGetter,
+ object?: MaybeRefOrGetter,
+ graph?: MaybeRefOrGetter,
+ options?: MaybeRefOrGetter>,
+ ): Ref> {
+ const createLdo = computed(() => {
+ const predicateValue = toValue(predicate);
+ const objectValue = toValue(object);
+ const graphValue = toValue(graph);
+ return (builder: LdoBuilder) =>
+ builder.matchSubject(predicateValue, objectValue, graphValue);
+ });
+
+ return useTrackingProxy(
+ shapeType,
+ createLdo,
+ () => toValue(options)?.dataset ?? dataset,
+ );
+ };
+}
diff --git a/packages/vue/src/methods/useResource.ts b/packages/vue/src/methods/useResource.ts
new file mode 100644
index 00000000..3e9d894e
--- /dev/null
+++ b/packages/vue/src/methods/useResource.ts
@@ -0,0 +1,149 @@
+import type {
+ ConnectedPlugin,
+ GetResourceReturnType,
+ IConnectedLdoDataset,
+ Resource,
+} from "@ldo/connected";
+import {
+ shallowRef,
+ watch,
+ onBeforeUnmount,
+ type Ref,
+ triggerRef,
+ type MaybeRefOrGetter,
+ toValue,
+} from "vue";
+
+export interface UseResourceOptions {
+ pluginName?: Name;
+ suppressInitialRead?: boolean;
+ reloadOnMount?: boolean;
+ subscribe?: boolean;
+}
+
+export type useResourceType = {
+ <
+ Name extends Plugins[number]["name"],
+ Plugin extends Extract,
+ UriType extends string,
+ >(
+ uri: MaybeRefOrGetter,
+ options?: MaybeRefOrGetter>,
+ ): Ref>;
+ <
+ Name extends Plugins[number]["name"],
+ Plugin extends Extract,
+ UriType extends string,
+ >(
+ uri?: MaybeRefOrGetter,
+ options?: MaybeRefOrGetter>,
+ ): Ref | undefined>;
+};
+
+/**
+ * @internal
+ *
+ * Creates a useResource composable.
+ */
+export function createUseResource(
+ dataset: IConnectedLdoDataset,
+): useResourceType {
+ /**
+ * Returns a reactive resource and triggers a rerender if that resource is updated.
+ */
+ return function useResource<
+ Name extends Plugins[number]["name"],
+ Plugin extends Extract,
+ UriType extends string,
+ >(
+ uri?: MaybeRefOrGetter,
+ options?: MaybeRefOrGetter>,
+ ): Ref | undefined> {
+ const resourceRef: Ref = shallowRef<
+ Resource | undefined
+ >();
+ let subscriptionId: string | undefined;
+
+ const onResourceUpdate = () => {
+ triggerRef(resourceRef);
+ };
+
+ watch(
+ [() => toValue(uri), () => toValue(options)],
+ async ([newUri, newOptions], [oldUri, oldOptions], onCleanup) => {
+ // if (newUri === oldUri && newOptions === oldOptions) return;
+ // TODO handle change in uri vs options more carefully
+
+ let cancelled = false;
+ let localResource: Resource | undefined;
+
+ onCleanup(async () => {
+ cancelled = true;
+ localResource?.off("update", onResourceUpdate);
+ });
+
+ const uriChanged = oldUri !== newUri;
+ const subscriptionTurnedOff = !newOptions?.subscribe;
+
+ if (uriChanged || subscriptionTurnedOff) {
+ if (subscriptionId) {
+ const sid = subscriptionId;
+ await resourceRef.value?.unsubscribeFromNotifications(sid);
+ // clear old subscription id
+ // but make sure we don't unintentionally clear a new subscription id
+ if (sid === subscriptionId) subscriptionId = undefined;
+ onResourceUpdate();
+ }
+ }
+
+ if (newUri) {
+ localResource = dataset.getResource(newUri) as Resource;
+ resourceRef.value = localResource;
+ if (!newOptions?.suppressInitialRead) {
+ if (newOptions?.reloadOnMount) {
+ resourceRef.value!.read();
+ } else {
+ resourceRef.value!.readIfUnfetched();
+ }
+ }
+
+ if (resourceRef.value) {
+ resourceRef.value.on("update", onResourceUpdate);
+ // Subscribe to notifications if it's needed
+ if (
+ newOptions?.subscribe &&
+ (uriChanged || !oldOptions?.subscribe)
+ ) {
+ const id = await resourceRef.value.subscribeToNotifications();
+ onResourceUpdate();
+
+ if (cancelled) {
+ await resourceRef.value.unsubscribeFromNotifications(id);
+ onResourceUpdate();
+ } else {
+ subscriptionId = id;
+ }
+ }
+ }
+ } else {
+ resourceRef.value = undefined;
+ }
+ },
+ { immediate: true },
+ );
+
+ // cleanup
+ onBeforeUnmount(() => {
+ resourceRef.value?.off("update", onResourceUpdate);
+ if (subscriptionId) {
+ resourceRef.value?.unsubscribeFromNotifications(subscriptionId);
+ subscriptionId = undefined;
+ }
+ });
+
+ return resourceRef as Ref<
+ GetResourceReturnType | undefined,
+ GetResourceReturnType
+ >;
+ };
+}
diff --git a/packages/vue/src/methods/useSubject.ts b/packages/vue/src/methods/useSubject.ts
new file mode 100644
index 00000000..2bbe727c
--- /dev/null
+++ b/packages/vue/src/methods/useSubject.ts
@@ -0,0 +1,58 @@
+import type { SubjectNode } from "@ldo/rdf-utils";
+import type { ShapeType, LdoBase, LdoBuilder } from "@ldo/ldo";
+import { useTrackingProxy } from "../util/useTrackingProxy";
+import type { ConnectedPlugin, IConnectedLdoDataset } from "@ldo/connected";
+import { computed, toValue, type MaybeRefOrGetter, type Ref } from "vue";
+
+export interface UseSubjectOptions {
+ dataset?: IConnectedLdoDataset;
+}
+
+export type useSubjectType = {
+ (
+ shapeType: MaybeRefOrGetter>,
+ subject: MaybeRefOrGetter,
+ options?: MaybeRefOrGetter>,
+ ): Ref;
+ (
+ shapeType: MaybeRefOrGetter>,
+ subject?: MaybeRefOrGetter,
+ options?: MaybeRefOrGetter>,
+ ): Ref;
+ (
+ shapeType: MaybeRefOrGetter>,
+ subject?: MaybeRefOrGetter,
+ options?: MaybeRefOrGetter>,
+ ): Ref;
+};
+
+/**
+ * @internal
+ *
+ * Creates a useSubject composable.
+ */
+export function createUseSubject(
+ dataset: IConnectedLdoDataset,
+): useSubjectType {
+ /**
+ * Returns a reactive Linked Data Object based on the provided subject.
+ * Triggers a rerender if the data are updated.
+ */
+ return function useSubject(
+ shapeType: MaybeRefOrGetter>,
+ subject?: MaybeRefOrGetter,
+ options?: MaybeRefOrGetter>,
+ ): Ref {
+ const createLdo = computed(() => {
+ const subjectValue = toValue(subject);
+ if (!subjectValue) return undefined;
+ return (builder: LdoBuilder) => builder.fromSubject(subjectValue);
+ });
+
+ return useTrackingProxy(
+ shapeType,
+ createLdo,
+ () => toValue(options)?.dataset ?? dataset,
+ );
+ };
+}
diff --git a/packages/vue/src/methods/useSubscribeToResource.ts b/packages/vue/src/methods/useSubscribeToResource.ts
new file mode 100644
index 00000000..5f314cf8
--- /dev/null
+++ b/packages/vue/src/methods/useSubscribeToResource.ts
@@ -0,0 +1,66 @@
+import type { ConnectedPlugin, IConnectedLdoDataset } from "@ldo/connected";
+import { onBeforeUnmount, toValue, watch, type MaybeRefOrGetter } from "vue";
+
+/**
+ * @internal
+ *
+ * Creates a useSubscribeToResource composable.
+ */
+export function createUseSubscribeToResource(
+ dataset: IConnectedLdoDataset,
+) {
+ /**
+ * Starts and updates subscriptions to a list of resources.
+ */
+ return function useSubscribeToResource(
+ uris: MaybeRefOrGetter,
+ ): void {
+ const currentlySubscribed: Record = {};
+
+ watch(
+ () => toValue(uris),
+ async (newUris) => {
+ const resources = newUris.map((uri) => dataset.getResource(uri));
+ const previousSubscriptions = { ...currentlySubscribed };
+
+ await Promise.all(
+ resources.map(async (resource) => {
+ if (!previousSubscriptions[resource.uri]) {
+ // Prevent multiple triggers from created subscriptions while waiting
+ // for connection
+ currentlySubscribed[resource.uri] = "AWAITING";
+ const _result = await resource.readIfUnfetched();
+ currentlySubscribed[resource.uri] =
+ await resource.subscribeToNotifications();
+ } else {
+ delete previousSubscriptions[resource.uri];
+ }
+ }),
+ );
+
+ await Promise.all(
+ Object.entries(previousSubscriptions).map(
+ async ([resourceUri, subscriptionId]) => {
+ // Unsubscribe
+ delete currentlySubscribed[resourceUri];
+ const resource = dataset.getResource(resourceUri);
+ await resource.unsubscribeFromNotifications(subscriptionId);
+ },
+ ),
+ );
+ },
+ { deep: true, immediate: true }, // also detect edits of the array in-place
+ );
+
+ onBeforeUnmount(async () => {
+ await Promise.all(
+ Object.entries(currentlySubscribed).map(
+ async ([resourceUri, subscriptionId]) => {
+ const resource = dataset.getResource(resourceUri);
+ await resource.unsubscribeFromNotifications(subscriptionId);
+ },
+ ),
+ );
+ });
+ };
+}
diff --git a/packages/vue/src/util/useTrackingProxy.ts b/packages/vue/src/util/useTrackingProxy.ts
new file mode 100644
index 00000000..36f65abd
--- /dev/null
+++ b/packages/vue/src/util/useTrackingProxy.ts
@@ -0,0 +1,72 @@
+import type { LdoBuilder } from "@ldo/ldo";
+import type { LdoBase, LdoDataset, ShapeType } from "@ldo/ldo";
+import { createTrackingProxyBuilder } from "@ldo/connected";
+import {
+ type MaybeRefOrGetter,
+ type Ref,
+ shallowRef,
+ toValue,
+ triggerRef,
+ watch,
+} from "vue";
+
+/**
+ * @internal
+ *
+ * A composable for tracking proxies.
+ */
+export function useTrackingProxy(
+ shapeType: MaybeRefOrGetter>,
+ createLdo: MaybeRefOrGetter<(builder: LdoBuilder) => ReturnType>,
+ dataset: MaybeRefOrGetter,
+): Ref;
+export function useTrackingProxy(
+ shapeType: MaybeRefOrGetter>,
+ createLdo: MaybeRefOrGetter,
+ dataset: MaybeRefOrGetter,
+): Ref;
+export function useTrackingProxy(
+ shapeType: MaybeRefOrGetter>,
+ createLdo: MaybeRefOrGetter<
+ ((builder: LdoBuilder) => ReturnType) | undefined
+ >,
+ dataset: MaybeRefOrGetter,
+): Ref;
+export function useTrackingProxy(
+ shapeType: MaybeRefOrGetter>,
+ createLdo: MaybeRefOrGetter<
+ ((builder: LdoBuilder) => ReturnType) | undefined
+ >,
+ dataset: MaybeRefOrGetter,
+): Ref {
+ const linkedDataObject = shallowRef() as Ref<
+ ReturnType | undefined
+ >;
+
+ const forceUpdate = () => {
+ triggerRef(linkedDataObject);
+ };
+
+ watch(
+ [
+ () => toValue(shapeType),
+ () => toValue(createLdo),
+ () => toValue(dataset),
+ ],
+ ([currentShapeType, currentCreateLdo, currentDataset], _, onCleanup) => {
+ onCleanup(() => {
+ currentDataset.removeListenerFromAllEvents(forceUpdate);
+ });
+
+ const builder = createTrackingProxyBuilder(
+ currentDataset,
+ currentShapeType,
+ forceUpdate,
+ );
+ linkedDataObject.value = currentCreateLdo?.(builder);
+ },
+ { immediate: true },
+ );
+
+ return linkedDataObject;
+}
diff --git a/packages/vue/test/Composables.test.ts b/packages/vue/test/Composables.test.ts
new file mode 100644
index 00000000..8b2fdc7d
--- /dev/null
+++ b/packages/vue/test/Composables.test.ts
@@ -0,0 +1,924 @@
+import { describe, it, beforeEach, expect, vi } from "vitest";
+import {
+ createLdoVueMethods,
+ createUseMatchObject,
+ createUseResource,
+ createUseSubscribeToResource,
+ type UseResourceOptions,
+} from "../src/index";
+import {
+ type SolidConnectedPlugin,
+ solidConnectedPlugin,
+ type SolidContainerUri,
+ type SolidLeafUri,
+} from "@ldo/connected-solid";
+import { RerenderCount, waitForResource, withSetup } from "./test-utils";
+import assert from "node:assert";
+import { setupServer } from "@ldo/test-solid-server";
+import { nextTick, type Ref, ref } from "vue";
+import { FoafProfileShapeType } from "./_ldo/foafProfile.shapeTypes";
+import { BasicLdSet } from "@ldo/jsonld-dataset-proxy";
+import { literal, namedNode, quad } from "@ldo/rdf-utils";
+import {
+ ConnectedLdoTransactionDataset,
+ createConnectedLdoDataset,
+ type IConnectedLdoDataset,
+} from "@ldo/connected";
+
+// Only overwrite this if we are in test mode. This is an env var we happen to have in our repo
+if (process.env.VITE_IS_TEST === "true") {
+ class ESBuildAndJSDOMCompatibleTextEncoder extends TextEncoder {
+ constructor() {
+ super();
+ }
+
+ encode(input: string) {
+ if (typeof input !== "string") {
+ throw new TypeError("`input` must be a string");
+ }
+
+ const decodedURI = decodeURIComponent(encodeURIComponent(input));
+ const arr = new Uint8Array(decodedURI.length);
+ const chars = decodedURI.split("");
+ for (let i = 0; i < chars.length; i++) {
+ arr[i] = decodedURI[i].charCodeAt(0);
+ }
+ return arr;
+ }
+ }
+
+ Object.defineProperty(global, "TextEncoder", {
+ value: ESBuildAndJSDOMCompatibleTextEncoder,
+ writable: true,
+ });
+}
+
+describe("LDO Vue Composables", () => {
+ let methods: ReturnType>;
+ const personResourceUri = "http://localhost:3006/directory/person";
+ const personUri = `${personResourceUri}#me`;
+ const otherPersonUri = `${personResourceUri}#i`;
+ const person2ResourceUri = "http://localhost:3006/directory/person2";
+ const person2Uri = `${person2ResourceUri}#me`;
+ const foafName = namedNode("http://xmlns.com/foaf/0.1/name");
+ const foafKnows = namedNode("http://xmlns.com/foaf/0.1/knows");
+
+ const s = setupServer(3006, {
+ slug: "directory/",
+ isContainer: true,
+ contains: [
+ {
+ slug: "leaf",
+ isContainer: false,
+ data: " .",
+ mimeType: "text/turtle",
+ },
+ {
+ slug: "person",
+ isContainer: false,
+ data: `
+ @prefix foaf: .
+ <> a foaf:PersonalProfileDocument.
+ <#me>
+ a foaf:Person;
+ foaf:name "Name";
+ foaf:knows , .
+
+ <#i> a foaf:Person; foaf:name "myname".
+ `,
+ mimeType: "text/turtle",
+ },
+ {
+ slug: "person2",
+ isContainer: false,
+ data: `
+ @prefix foaf: .
+ <#me> a foaf:Person; foaf:name "Other Name"; foaf:knows <./person#me>.
+ `,
+ mimeType: "text/turtle",
+ },
+ ],
+ });
+
+ beforeEach(() => {
+ methods = createLdoVueMethods([solidConnectedPlugin]);
+ methods.dataset.setContext("solid", { fetch: s.fetchMock });
+ });
+
+ describe("useTrackingProxy", () => {
+ it.todo("should return a LinkedDataObject");
+ });
+
+ describe("useResource", () => {
+ it("should fetch a resource by uri", async () => {
+ const [result, app] = withSetup(() =>
+ methods.useResource("http://localhost:3006/directory/"),
+ );
+
+ expect(result.value.isFetched()).toBe(false);
+
+ await waitForResource(result.value);
+
+ expect(result.value.isFetched()).toBe(true);
+
+ expect(result.value.type).toEqual("SolidContainer");
+
+ const headersResult = await result.value.getHeaders();
+ expect(headersResult.isError).toBe(false);
+
+ const rootContainerResult = await result.value.getRootContainer();
+
+ assert(!rootContainerResult.isError);
+ expect(rootContainerResult.uri).toEqual("http://localhost:3006/");
+
+ app.unmount();
+ });
+
+ it("should fetch the new resource when uri changes", async () => {
+ const uriRef = ref("http://localhost:3006/directory/");
+ const [result, app] = withSetup(() => methods.useResource(uriRef));
+
+ expect(result.value.isFetched()).toBe(false);
+
+ await waitForResource(result.value);
+
+ expect(result.value.isFetched()).toBe(true);
+ expect(result.value.type).toEqual("SolidContainer");
+
+ uriRef.value = "http://localhost:3006/directory/leaf";
+ await nextTick();
+
+ expect(result.value.isFetched()).toBe(false);
+ expect(result.value.uri).toEqual("http://localhost:3006/directory/leaf");
+
+ await waitForResource(result.value);
+
+ expect(result.value.isFetched()).toBe(true);
+ expect(result.value.type).toEqual("SolidLeaf");
+
+ app.unmount();
+ });
+
+ it("should handle change in options", async () => {
+ const uriRef: Ref = ref(
+ "http://localhost:3006/directory/",
+ );
+ const optionsRef: Ref> = ref({
+ suppressInitialRead: true,
+ });
+ const [result, app] = withSetup(() =>
+ methods.useResource(uriRef, optionsRef),
+ );
+
+ expect(result.value.isFetched()).toBe(false);
+
+ await new Promise((resolve) => setTimeout(resolve, 500));
+
+ expect(result.value.isFetched()).toBe(false);
+
+ optionsRef.value = { suppressInitialRead: false };
+
+ await waitForResource(result.value);
+
+ expect(result.value.isFetched()).toBe(true);
+
+ expect(s.fetchMock).toHaveBeenCalledTimes(1);
+
+ app.unmount();
+ });
+ });
+
+ describe("useSubject", () => {
+ it("should return a linked data object with given subject uri", async () => {
+ const [result, app] = withSetup(() => {
+ const useSubjectResult = methods.useSubject(
+ FoafProfileShapeType,
+ "http://localhost:3006/directory/person#me",
+ );
+ const useResourceResult = methods.useResource(
+ "http://localhost:3006/directory/person",
+ );
+
+ return [useSubjectResult, useResourceResult] as const;
+ });
+
+ const rerenderCount = new RerenderCount(result);
+
+ expect(rerenderCount.count).toEqual(0);
+
+ await waitForResource(result[1].value);
+
+ expect(rerenderCount.count).toEqual(1);
+
+ assert(!result[1].value.isError);
+ expect(result[1].value.isAbsent()).toBe(false);
+
+ expect(result[0].value.name).toEqual("Name");
+ const knows = result[0].value.knows?.map((k) => k["@id"]);
+ expect(knows).toHaveLength(2);
+ expect(knows).toContain("https://example.com/profile/card#me");
+ expect(knows).toContain("https://example.org/profile/card#i");
+
+ app.unmount();
+ });
+
+ it("should change the LDO when the subject changes", async () => {
+ // s.fetchMock.mockClear();
+
+ const subject = ref("http://localhost:3006/directory/person#me");
+
+ expect(s.fetchMock).toHaveBeenCalledTimes(0);
+
+ const [result, app] = withSetup(() => {
+ const useSubjectResult = methods.useSubject(
+ FoafProfileShapeType,
+ subject,
+ );
+
+ const useResourceResult = methods.useResource(
+ subject as Ref,
+ );
+
+ return [useSubjectResult, useResourceResult] as const;
+ });
+
+ const rerenderCount = new RerenderCount(result[0]);
+
+ // inform the tracking proxy we're interested in this and check the result
+ // removing access to the property will lead to less renders
+ expect(result[0].value.name).toEqual(undefined);
+
+ expect(rerenderCount.count).toEqual(0);
+
+ await waitForResource(result[1].value);
+
+ expect(result[0].value.name).toEqual("Name");
+ expect(rerenderCount.count).toEqual(1);
+
+ subject.value = "http://localhost:3006/directory/person#i";
+
+ // this should not trigger refetch
+ await nextTick();
+
+ expect(result[1].value.isFetched()).toBe(true);
+ expect(rerenderCount.count).toEqual(2);
+ expect(result[0].value.name).toEqual("myname");
+
+ subject.value = "http://localhost:3006/directory/person2#me";
+
+ // this triggers refetch
+ await nextTick();
+ expect(result[1].value.isFetched()).toBe(false);
+ expect(result[0].value.name).toEqual(undefined);
+ expect(rerenderCount.count).toEqual(3);
+
+ await waitForResource(result[1].value);
+
+ expect(result[1].value.isFetched()).toBe(true);
+ expect(result[1].value.isAbsent()).toBe(false);
+ expect(result[0].value.name).toEqual("Other Name");
+ expect(rerenderCount.count).toEqual(4);
+
+ app.unmount();
+ });
+
+ it.todo(
+ "should change the LDO when the shape type changes (this will probably ruin types though)",
+ );
+ it.todo("should change the LDO when the options.dataset changes");
+ });
+
+ describe("useMatchSubject", () => {
+ it("should return a LdSet of matched linked data objects", async () => {
+ const [result, app] = withSetup(() => {
+ const useMatchSubjectResult = methods.useMatchSubject(
+ FoafProfileShapeType,
+ "http://www.w3.org/1999/02/22-rdf-syntax-ns#type",
+ "http://xmlns.com/foaf/0.1/Person",
+ );
+ const useResourceResult = methods.useResource(
+ "http://localhost:3006/directory/person",
+ );
+
+ return [useMatchSubjectResult, useResourceResult] as const;
+ });
+
+ await waitForResource(result[1].value);
+
+ assert(!result[1].value.isError);
+ expect(result[1].value.isAbsent()).toBe(false);
+
+ expect(result[0].value).toBeInstanceOf(BasicLdSet);
+ expect(result[0].value.size).toBe(2);
+ expect(result[0].value.map((v) => v["@id"])).toContain(
+ "http://localhost:3006/directory/person#me",
+ );
+ expect(result[0].value.map((v) => v["@id"])).toContain(
+ "http://localhost:3006/directory/person#i",
+ );
+
+ app.unmount();
+ });
+ it.todo(
+ "should change the LDO set when the shape type changes (this will probably ruin types though)",
+ );
+ it.todo("should change the LDO set when the options.dataset changes");
+ it.todo("should change the LDO set when predicate changes");
+
+ it("should change the LDO set when object changes", async () => {
+ const object = ref("http://xmlns.com/foaf/0.1/Person");
+
+ const [result, app] = withSetup(() => {
+ const useMatchSubjectResult = methods.useMatchSubject(
+ FoafProfileShapeType,
+ "http://www.w3.org/1999/02/22-rdf-syntax-ns#type",
+ object,
+ undefined,
+ );
+ const useResourceResult = methods.useResource(
+ "http://localhost:3006/directory/person",
+ );
+
+ return [useMatchSubjectResult, useResourceResult] as const;
+ });
+
+ const rerenderCount = new RerenderCount(result);
+
+ expect(result[0].value.size).toBe(0);
+
+ await waitForResource(result[1].value);
+
+ expect(rerenderCount.count).toBe(2);
+
+ assert(!result[1].value.isError);
+ expect(result[1].value.isAbsent()).toBe(false);
+
+ expect(result[0].value).toBeInstanceOf(BasicLdSet);
+ expect(result[0].value.size).toBe(2);
+ expect(result[0].value.map((v) => v["@id"])).toContain(
+ "http://localhost:3006/directory/person#me",
+ );
+ expect(result[0].value.map((v) => v["@id"])).toContain(
+ "http://localhost:3006/directory/person#i",
+ );
+
+ object.value = "http://xmlns.com/foaf/0.1/PersonalProfileDocument";
+ await nextTick();
+ expect(result[0].value.size).toBe(1);
+
+ result[0].value.forEach((v) => {
+ expect(v["@id"]).toBe("http://localhost:3006/directory/person");
+ });
+
+ // TODO fix, it does update in production though
+ expect(rerenderCount.count).toBe(3);
+
+ app.unmount();
+ });
+
+ it.todo("should change the LDO set when graph changes");
+ });
+
+ describe("useMatchObject", () => {
+ it("should return a LdSet of matched linked data objects", async () => {
+ const [result, app] = withSetup(() => {
+ const useMatchObjectResult = methods.useMatchObject(
+ FoafProfileShapeType,
+ "http://localhost:3006/directory/person#me",
+ "http://xmlns.com/foaf/0.1/knows",
+ "http://localhost:3006/directory/person",
+ );
+ const useResourceResult = methods.useResource(
+ "http://localhost:3006/directory/person",
+ );
+
+ return [useMatchObjectResult, useResourceResult] as const;
+ });
+
+ await waitForResource(result[1].value);
+
+ assert(!result[1].value.isError);
+ expect(result[1].value.isAbsent()).toBe(false);
+
+ const friends = result[0].value;
+ expect(friends.size).toBe(2);
+ expect(friends.map((v) => v["@id"])).toContain(
+ "https://example.com/profile/card#me",
+ );
+ expect(friends.map((v) => v["@id"])).toContain(
+ "https://example.org/profile/card#i",
+ );
+
+ app.unmount();
+ });
+
+ it.todo("should change the LDO set when the shape type changes");
+ it.todo("should change the LDO set when the options.dataset changes");
+ it.todo("should change the LDO set when subject changes");
+ it.todo("should change the LDO set when predicate changes");
+ it.todo("should change the LDO set when graph changes");
+ });
+
+ describe("useSubscribeToResource", () => {
+ it("should subscribe to resource changes (detect resource changes)", async () => {
+ // subscribe
+ const [result, app] = withSetup(
+ () =>
+ [
+ methods.useSubscribeToResource([personResourceUri]),
+ methods.useSubject(FoafProfileShapeType, personUri),
+ ] as const,
+ );
+
+ void result[1].value.name;
+ const rerenderCount = new RerenderCount(result[1]);
+
+ // change the resource
+ const resource = methods.dataset.getResource(personResourceUri);
+
+ await vi.waitFor(() => {
+ expect(resource.isFetched()).toBe(true);
+ });
+ await vi.waitFor(() => {
+ expect(resource.isSubscribedToNotifications()).toBe(true);
+ });
+ // check that the change has been detected
+ rerenderCount.clearCount();
+ const changeResult = await s.authFetch(personResourceUri, {
+ method: "PATCH",
+ headers: { "content-type": "text/n3" },
+ body: `
+ @prefix solid: .
+ @prefix foaf: .
+
+ _:patch a solid:InsertDeletePatch;
+ solid:inserts { <#me> foaf:name "NEW NAME". };
+ solid:deletes { <#me> foaf:name ?name. };
+ solid:where { <#me> foaf:name ?name. }.`,
+ });
+ expect(changeResult.ok).toBe(true);
+ await nextTick();
+ // refetch should be going on
+ await vi.waitFor(() => {
+ expect(resource.isLoading()).toBe(true);
+ });
+ // and then done
+ await vi.waitFor(() => expect(resource.isLoading()).toBe(false));
+ expect(resource.isError).toBe(false);
+ // and expect refreshed data
+ expect(result[1].value.name).toEqual("NEW NAME");
+ await nextTick();
+ // expect(rerenderCount.count).toEqual(1);
+
+ app.unmount();
+ });
+
+ it("should unsubscribe from resources removed", async () => {
+ const urlRef = ref([personResourceUri]);
+ // subscribe
+ const [, app] = withSetup(
+ () =>
+ [
+ methods.useSubscribeToResource(urlRef),
+ methods.useSubject(FoafProfileShapeType, personUri),
+ ] as const,
+ );
+
+ const resource = methods.dataset.getResource(personResourceUri);
+ await vi.waitFor(() => {
+ expect(resource.isFetched()).toBe(true);
+ });
+ await vi.waitFor(() => {
+ expect(resource.isSubscribedToNotifications()).toBe(true);
+ });
+
+ // remove resource from subscription
+ urlRef.value = [];
+
+ // and check that it's not subscribed, eventually
+ await vi.waitFor(() => {
+ expect(resource.isSubscribedToNotifications()).toBe(false);
+ });
+
+ app.unmount();
+ });
+
+ it("should unsubscribe from resources when finished", async () => {
+ // subscribe
+ const [, app] = withSetup(
+ () =>
+ [
+ methods.useSubscribeToResource([personResourceUri]),
+ methods.useSubject(FoafProfileShapeType, personUri),
+ ] as const,
+ );
+
+ const resource = methods.dataset.getResource(personResourceUri);
+ await vi.waitFor(() => {
+ expect(resource.isFetched()).toBe(true);
+ });
+ await vi.waitFor(() => {
+ expect(resource.isSubscribedToNotifications()).toBe(true);
+ });
+
+ // unmount
+ app.unmount();
+
+ // and check that the resource is not subscribed, eventually
+ await vi.waitFor(() => {
+ expect(resource.isSubscribedToNotifications()).toBe(false);
+ });
+ });
+ });
+
+ describe("useLinkQuery", () => {
+ it("should resolve the query", async () => {
+ const [result, app] = withSetup(() =>
+ methods.useLinkQuery(
+ FoafProfileShapeType,
+ person2ResourceUri,
+ person2Uri,
+ { name: true, knows: { name: true, "@id": true } },
+ ),
+ );
+
+ const person2Resource = methods.dataset.getResource(person2ResourceUri);
+ const personResource = methods.dataset.getResource(personResourceUri);
+
+ await vi.waitFor(() => {
+ expect(person2Resource.isFetched()).toBe(true);
+ expect(personResource.isFetched()).toBe(true);
+ });
+
+ // test result
+ expect(result.value.knows?.map((k) => k.name)).toEqual(["Name"]);
+
+ // wait for resources to be subscribed to notifications
+ await vi.waitFor(() => {
+ expect(person2Resource.isSubscribedToNotifications()).toBe(true);
+ expect(personResource.isSubscribedToNotifications()).toBe(true);
+ });
+
+ app.unmount();
+
+ // wait for the resources to be unsubscribed from notifications after unmount
+ await vi.waitFor(() => {
+ expect(person2Resource.isSubscribedToNotifications()).toBe(false);
+ expect(personResource.isSubscribedToNotifications()).toBe(false);
+ });
+ });
+ it.todo("should update the query when a resource changes");
+ });
+
+ describe("useChangeDataset", () => {
+ it("should accept and commit changes to a default dataset", async () => {
+ const [results, app] = withSetup(() => {
+ const changeDataset = methods.useChangeDataset();
+ const resource = methods.useResource(personResourceUri);
+ methods.useSubscribeToResource([personResourceUri]);
+
+ return { changeDataset, resource };
+ });
+
+ expect(results.changeDataset.transactionDataset.value).toBeInstanceOf(
+ ConnectedLdoTransactionDataset,
+ );
+
+ // make sure the resource is fetched before proceeding
+ await vi.waitFor(() => {
+ expect(results.resource.value.isFetched()).toBe(true);
+ });
+ // make sure resource will update
+ await vi.waitFor(() => {
+ expect(results.resource.value.isSubscribedToNotifications()).toBe(true);
+ });
+
+ // change person's name
+ results.changeDataset.setData((dataset) => {
+ dataset.deleteMatches(namedNode(personUri), foafName);
+ dataset.add(
+ quad(
+ namedNode(personUri),
+ foafName,
+ literal("New Saved Name"),
+ namedNode(personResourceUri),
+ ),
+ );
+ });
+
+ expect(
+ results.changeDataset.transactionDataset.value.getChanges().added?.size,
+ ).toEqual(1);
+ expect(
+ results.changeDataset.transactionDataset.value.getChanges().removed
+ ?.size,
+ ).toEqual(1);
+ const result = await results.changeDataset.commitData();
+ expect(result.isError).toBe(false);
+ // transaction dataset should be reset at this point
+ expect(
+ results.changeDataset.transactionDataset.value.getChanges(),
+ ).toEqual({});
+
+ // the resource should reload (thanks to subscription)
+ await vi.waitFor(() => {
+ expect(results.resource.value.isLoading()).toBe(true);
+ });
+ await vi.waitFor(() => {
+ expect(results.resource.value.isLoading()).toBe(false);
+ });
+
+ const names = methods.dataset.match(namedNode(personUri), foafName);
+
+ // and the name should be updated
+ expect(names.size).toBe(1);
+ expect(names.toArray()[0].object.value).toBe("New Saved Name");
+
+ app.unmount();
+
+ // let's just wait for unsubscribing at the end
+ await vi.waitFor(() => {
+ expect(results.resource.value.isLoading()).toBe(false);
+ });
+ });
+
+ it.todo("should handle changes to custom dataset");
+ it.todo("should handle error in saving");
+ });
+
+ describe("useChangeSubject", () => {
+ it("should accept and commit changes to a default dataset", async () => {
+ const [{ changeDataset, resource, subject, otherSubject }, app] =
+ withSetup(() => {
+ const changeDataset = methods.useChangeSubject(
+ FoafProfileShapeType,
+ personUri,
+ );
+ const resource = methods.useResource(personResourceUri);
+ const subject = methods.useSubject(FoafProfileShapeType, personUri);
+ const otherSubject = methods.useSubject(
+ FoafProfileShapeType,
+ otherPersonUri,
+ );
+ return { changeDataset, resource, subject, otherSubject };
+ });
+
+ await vi.waitFor(() => {
+ expect(resource.value.isFetched()).toBe(true);
+ });
+
+ changeDataset.setData(resource.value, (profile) => {
+ profile.name = "ANOTHER NAME";
+ });
+ changeDataset.setData(
+ resource.value,
+ (profile) => {
+ profile.name = "OTHER PERSON NAME";
+ },
+ otherSubject.value,
+ );
+
+ const result = await changeDataset.commitData();
+ expect(result.isError).toBe(false);
+ expect(subject.value.name).toEqual("ANOTHER NAME");
+ expect(otherSubject.value.name).toEqual("OTHER PERSON NAME");
+
+ app.unmount();
+ });
+
+ it.todo("should accept and commit changes to a custom dataset");
+ it.todo("should handle error in saving");
+ });
+
+ describe("useChangeMatchObject", () => {
+ it("should accept and commit changes to a default dataset", async () => {
+ const [{ changeDataset, resource, resource2, objects, subject }, app] =
+ withSetup(() => {
+ const changeDataset = methods.useChangeMatchObject(
+ FoafProfileShapeType,
+ person2Uri,
+ foafKnows,
+ );
+ const resource = methods.useResource(personResourceUri);
+ const resource2 = methods.useResource(person2ResourceUri);
+ const subject = methods.useSubject(FoafProfileShapeType, person2Uri);
+ const objects = methods.useMatchObject(
+ FoafProfileShapeType,
+ person2Uri,
+ foafKnows,
+ );
+ methods.useSubscribeToResource([
+ personResourceUri,
+ person2ResourceUri,
+ ]);
+ return { changeDataset, resource, resource2, objects, subject };
+ });
+
+ await vi.waitFor(() => {
+ expect(resource.value.isFetched()).toBe(true);
+ expect(resource2.value.isFetched()).toBe(true);
+ });
+ await vi.waitFor(() => {
+ expect(resource.value.isSubscribedToNotifications()).toBe(true);
+ expect(resource2.value.isSubscribedToNotifications()).toBe(true);
+ });
+
+ changeDataset.setData(resource.value, (friends) => {
+ expect(friends.size).toEqual(1);
+ friends.forEach((person) => {
+ person.name = "ANOTHER NAME";
+ });
+ });
+
+ // we can also edit other subjects and graphs (resources) within the same transaction
+ changeDataset.setData(
+ resource2.value,
+ (person) => {
+ person.name = "PERSON 2 NAME";
+ },
+ subject.value,
+ );
+
+ const result = await changeDataset.commitData();
+ expect(result.isError).toBe(false);
+
+ await vi.waitFor(() => {
+ expect(resource.value.isLoading()).toBe(true);
+ expect(resource2.value.isLoading()).toBe(true);
+ });
+ await vi.waitFor(() => {
+ expect(resource.value.isLoading()).toBe(false);
+ expect(resource2.value.isLoading()).toBe(false);
+ });
+
+ expect(objects.value.size).toBe(1);
+ expect(objects.value.toArray()[0].name).toEqual("ANOTHER NAME");
+ expect(subject.value.name).toEqual("PERSON 2 NAME");
+
+ app.unmount();
+ await vi.waitFor(() => {
+ expect(resource.value.isSubscribedToNotifications()).toBe(false);
+ expect(resource2.value.isSubscribedToNotifications()).toBe(false);
+ });
+ });
+
+ it("should accept and commit changes to a custom dataset", async () => {
+ const otherDataset = createConnectedLdoDataset([
+ solidConnectedPlugin,
+ ]) as IConnectedLdoDataset<[SolidConnectedPlugin]>;
+ otherDataset.setContext("solid", { fetch: s.fetchMock });
+ const useResource = createUseResource(otherDataset);
+ const useMatchObject = createUseMatchObject(otherDataset);
+ const useSubscribeToResource = createUseSubscribeToResource(otherDataset);
+ const [{ changeDataset, resource, resource2, objects }, app] = withSetup(
+ () => {
+ const changeDataset = methods.useChangeMatchObject(
+ FoafProfileShapeType,
+ person2Uri,
+ foafKnows,
+ undefined,
+ {
+ dataset: otherDataset as IConnectedLdoDataset<
+ [SolidConnectedPlugin]
+ >,
+ },
+ );
+ const resource = useResource(personResourceUri);
+ const resource2 = useResource(person2ResourceUri);
+ const objects = useMatchObject(
+ FoafProfileShapeType,
+ person2Uri,
+ foafKnows,
+ );
+ useSubscribeToResource([personResourceUri, person2ResourceUri]);
+ return { changeDataset, resource, resource2, objects };
+ },
+ );
+
+ await vi.waitFor(() => {
+ expect(resource.value.isFetched()).toBe(true);
+ expect(resource2.value.isFetched()).toBe(true);
+ });
+ await vi.waitFor(() => {
+ expect(resource.value.isSubscribedToNotifications()).toBe(true);
+ expect(resource2.value.isSubscribedToNotifications()).toBe(true);
+ });
+
+ changeDataset.setData(resource.value, (friends) => {
+ friends.forEach((person) => {
+ person.name = "ANOTHER NAME";
+ });
+ });
+
+ const result = await changeDataset.commitData();
+ expect(result.isError).toBe(false);
+
+ await vi.waitFor(() => {
+ expect(resource.value.isLoading()).toBe(true);
+ });
+ await vi.waitFor(() => {
+ expect(resource.value.isLoading()).toBe(false);
+ });
+
+ expect(objects.value.size).toBe(1);
+ expect(objects.value.toArray()[0].name).toEqual("ANOTHER NAME");
+
+ app.unmount();
+ await vi.waitFor(() => {
+ expect(resource.value.isSubscribedToNotifications()).toBe(false);
+ expect(resource2.value.isSubscribedToNotifications()).toBe(false);
+ });
+ });
+
+ it.todo("should handle error in saving");
+ });
+
+ describe("useChangeMatchSubject", () => {
+ it("should accept and commit changes to a default dataset", async () => {
+ const [{ changeDataset, resource, resource2, subjects, subject2 }, app] =
+ withSetup(() => {
+ // people in first resource who have friends
+ const changeDataset = methods.useChangeMatchSubject(
+ FoafProfileShapeType,
+ foafKnows,
+ undefined,
+ namedNode(personResourceUri),
+ );
+ const resource = methods.useResource(personResourceUri);
+ const resource2 = methods.useResource(person2ResourceUri);
+ const subject2 = methods.useSubject(FoafProfileShapeType, person2Uri);
+ const subjects = methods.useMatchSubject(
+ FoafProfileShapeType,
+ foafKnows,
+ undefined,
+ namedNode(personResourceUri),
+ );
+ methods.useSubscribeToResource([
+ personResourceUri,
+ person2ResourceUri,
+ ]);
+ return {
+ changeDataset,
+ resource,
+ resource2,
+ subjects,
+ subject2,
+ };
+ });
+
+ await vi.waitFor(() => {
+ expect(resource.value.isFetched()).toBe(true);
+ expect(resource2.value.isFetched()).toBe(true);
+ });
+ await vi.waitFor(() => {
+ expect(resource.value.isSubscribedToNotifications()).toBe(true);
+ expect(resource2.value.isSubscribedToNotifications()).toBe(true);
+ });
+
+ changeDataset.setData(resource.value, (people) => {
+ // expect(people.size).toEqual(1); // weirdly, this fails! TODO
+ let count = 0;
+ people.forEach((person) => {
+ count++;
+ person.name = "ANOTHER NAME";
+ });
+ expect(count).toBe(1);
+ });
+
+ // we can also edit other subjects and graphs (resources) within the same transaction
+ changeDataset.setData(
+ resource2.value,
+ (person) => {
+ person.name = "PERSON 2 NAME";
+ },
+ subject2.value,
+ );
+
+ const result = await changeDataset.commitData();
+ expect(result.isError).toBe(false);
+
+ await vi.waitFor(() => {
+ expect(resource.value.isLoading()).toBe(true);
+ expect(resource2.value.isLoading()).toBe(true);
+ });
+ await vi.waitFor(() => {
+ expect(resource.value.isLoading()).toBe(false);
+ expect(resource2.value.isLoading()).toBe(false);
+ });
+
+ // expect(subjects.value.size).toBe(1); // TODO weirdly, this fails
+ expect(subjects.value.toArray()).toHaveLength(1);
+ expect(subjects.value.toArray()[0].name).toEqual("ANOTHER NAME");
+ expect(subject2.value.name).toEqual("PERSON 2 NAME");
+
+ app.unmount();
+ await vi.waitFor(() => {
+ expect(resource.value.isSubscribedToNotifications()).toBe(false);
+ expect(resource2.value.isSubscribedToNotifications()).toBe(false);
+ });
+ });
+
+ it.todo("should accept and commit changes to a custom dataset");
+ it.todo("should handle error in saving");
+ });
+});
diff --git a/packages/vue/test/_ldo/foafProfile.context.ts b/packages/vue/test/_ldo/foafProfile.context.ts
new file mode 100644
index 00000000..e7a57dfc
--- /dev/null
+++ b/packages/vue/test/_ldo/foafProfile.context.ts
@@ -0,0 +1,48 @@
+import type { LdoJsonldContext } from "@ldo/ldo";
+
+/**
+ * =============================================================================
+ * foafProfileContext: JSONLD Context for foafProfile
+ * =============================================================================
+ */
+export const foafProfileContext: LdoJsonldContext = {
+ type: {
+ "@id": "@type",
+ "@isCollection": true,
+ },
+ Person: {
+ "@id": "http://xmlns.com/foaf/0.1/Person",
+ "@context": {
+ type: {
+ "@id": "@type",
+ "@isCollection": true,
+ },
+ name: {
+ "@id": "http://xmlns.com/foaf/0.1/name",
+ "@type": "http://www.w3.org/2001/XMLSchema#string",
+ },
+ img: {
+ "@id": "http://xmlns.com/foaf/0.1/img",
+ "@type": "http://www.w3.org/2001/XMLSchema#string",
+ },
+ knows: {
+ "@id": "http://xmlns.com/foaf/0.1/knows",
+ "@type": "@id",
+ "@isCollection": true,
+ },
+ },
+ },
+ name: {
+ "@id": "http://xmlns.com/foaf/0.1/name",
+ "@type": "http://www.w3.org/2001/XMLSchema#string",
+ },
+ img: {
+ "@id": "http://xmlns.com/foaf/0.1/img",
+ "@type": "http://www.w3.org/2001/XMLSchema#string",
+ },
+ knows: {
+ "@id": "http://xmlns.com/foaf/0.1/knows",
+ "@type": "@id",
+ "@isCollection": true,
+ },
+};
diff --git a/packages/vue/test/_ldo/foafProfile.schema.ts b/packages/vue/test/_ldo/foafProfile.schema.ts
new file mode 100644
index 00000000..25243cde
--- /dev/null
+++ b/packages/vue/test/_ldo/foafProfile.schema.ts
@@ -0,0 +1,97 @@
+import type { Schema } from "shexj";
+
+/**
+ * =============================================================================
+ * foafProfileSchema: ShexJ Schema for foafProfile
+ * =============================================================================
+ */
+export const foafProfileSchema: Schema = {
+ type: "Schema",
+ shapes: [
+ {
+ id: "https://example.com/FoafProfile",
+ type: "ShapeDecl",
+ shapeExpr: {
+ type: "Shape",
+ expression: {
+ type: "EachOf",
+ expressions: [
+ {
+ type: "TripleConstraint",
+ predicate: "http://www.w3.org/1999/02/22-rdf-syntax-ns#type",
+ valueExpr: {
+ type: "NodeConstraint",
+ values: ["http://xmlns.com/foaf/0.1/Person"],
+ },
+ annotations: [
+ {
+ type: "Annotation",
+ predicate: "http://www.w3.org/2000/01/rdf-schema#comment",
+ object: {
+ value: "Defines the node as a Person (from foaf)",
+ },
+ },
+ ],
+ },
+ {
+ type: "TripleConstraint",
+ predicate: "http://xmlns.com/foaf/0.1/name",
+ valueExpr: {
+ type: "NodeConstraint",
+ datatype: "http://www.w3.org/2001/XMLSchema#string",
+ },
+ min: 0,
+ max: 1,
+ annotations: [
+ {
+ type: "Annotation",
+ predicate: "http://www.w3.org/2000/01/rdf-schema#comment",
+ object: {
+ value: "Define a person's name.",
+ },
+ },
+ ],
+ },
+ {
+ type: "TripleConstraint",
+ predicate: "http://xmlns.com/foaf/0.1/img",
+ valueExpr: {
+ type: "NodeConstraint",
+ datatype: "http://www.w3.org/2001/XMLSchema#string",
+ },
+ min: 0,
+ max: 1,
+ annotations: [
+ {
+ type: "Annotation",
+ predicate: "http://www.w3.org/2000/01/rdf-schema#comment",
+ object: {
+ value: "Photo link but in string form",
+ },
+ },
+ ],
+ },
+ {
+ type: "TripleConstraint",
+ predicate: "http://xmlns.com/foaf/0.1/knows",
+ valueExpr: "https://example.com/FoafProfile",
+ min: 0,
+ max: -1,
+ annotations: [
+ {
+ type: "Annotation",
+ predicate: "http://www.w3.org/2000/01/rdf-schema#comment",
+ object: {
+ value:
+ "A list of WebIds for all the people this user knows.",
+ },
+ },
+ ],
+ },
+ ],
+ },
+ extra: ["http://www.w3.org/1999/02/22-rdf-syntax-ns#type"],
+ },
+ },
+ ],
+};
diff --git a/packages/vue/test/_ldo/foafProfile.shapeTypes.ts b/packages/vue/test/_ldo/foafProfile.shapeTypes.ts
new file mode 100644
index 00000000..2c52ee86
--- /dev/null
+++ b/packages/vue/test/_ldo/foafProfile.shapeTypes.ts
@@ -0,0 +1,19 @@
+import type { ShapeType } from "@ldo/ldo";
+import { foafProfileSchema } from "./foafProfile.schema";
+import { foafProfileContext } from "./foafProfile.context";
+import type { FoafProfile } from "./foafProfile.typings";
+
+/**
+ * =============================================================================
+ * LDO ShapeTypes foafProfile
+ * =============================================================================
+ */
+
+/**
+ * FoafProfile ShapeType
+ */
+export const FoafProfileShapeType: ShapeType = {
+ schema: foafProfileSchema,
+ shape: "https://example.com/FoafProfile",
+ context: foafProfileContext,
+};
diff --git a/packages/vue/test/_ldo/foafProfile.typings.ts b/packages/vue/test/_ldo/foafProfile.typings.ts
new file mode 100644
index 00000000..16843881
--- /dev/null
+++ b/packages/vue/test/_ldo/foafProfile.typings.ts
@@ -0,0 +1,33 @@
+import type { LdoJsonldContext, LdSet } from "@ldo/ldo";
+
+/**
+ * =============================================================================
+ * Typescript Typings for foafProfile
+ * =============================================================================
+ */
+
+/**
+ * FoafProfile Type
+ */
+export interface FoafProfile {
+ "@id"?: string;
+ "@context"?: LdoJsonldContext;
+ /**
+ * Defines the node as a Person (from foaf)
+ */
+ type: LdSet<{
+ "@id": "Person";
+ }>;
+ /**
+ * Define a person's name.
+ */
+ name?: string;
+ /**
+ * Photo link but in string form
+ */
+ img?: string;
+ /**
+ * A list of WebIds for all the people this user knows.
+ */
+ knows?: LdSet;
+}
diff --git a/packages/vue/test/test-utils.ts b/packages/vue/test/test-utils.ts
new file mode 100644
index 00000000..0ec07079
--- /dev/null
+++ b/packages/vue/test/test-utils.ts
@@ -0,0 +1,63 @@
+import type { Resource } from "@ldo/connected";
+import { vi } from "vitest";
+import {
+ createApp,
+ type MultiWatchSources,
+ watch,
+ type App,
+ type WatchSource,
+} from "vue";
+
+/**
+ * https://vuejs.org/guide/scaling-up/testing.html#testing-composables
+ */
+export function withSetup(composable: () => T): [T, App] {
+ let result!: T;
+ const app = createApp({
+ setup() {
+ result = composable();
+ // suppress missing template warning
+ return () => {};
+ },
+ });
+ app.mount(document.createElement("div"));
+ // return the result and the app instance
+ // for testing provide/unmount
+ return [result, app];
+}
+
+/**
+ * This counts how many times the reference or references updated.
+ * Constructor accepts any parameter that fits vue's watch source/sources parameter.
+ *
+ * https://vuejs.org/api/reactivity-core.html#watch
+ */
+type AllowedSources =
+ | WatchSource
+ | MultiWatchSources
+ | Readonly;
+export class RerenderCount {
+ private _count = 0;
+
+ constructor(sources: AllowedSources) {
+ watch(sources, () => {
+ this._count++;
+ });
+ }
+
+ public get count() {
+ return this._count;
+ }
+
+ public clearCount() {
+ this._count = 0;
+ }
+}
+
+export async function waitForResource(resource: Resource) {
+ await vi.waitFor(() => {
+ if (!resource.isFetched()) {
+ throw new Error("not fetched yet");
+ }
+ });
+}
diff --git a/packages/vue/tsconfig.esm.json b/packages/vue/tsconfig.esm.json
new file mode 100644
index 00000000..77952ca6
--- /dev/null
+++ b/packages/vue/tsconfig.esm.json
@@ -0,0 +1,9 @@
+{
+ "extends": "../../tsconfig.esm.json",
+ "compilerOptions": {
+ "outDir": "./dist/esm",
+ "rootDir": "./src",
+ "declarationDir": "./dist/types"
+ },
+ "include": ["src"]
+}
diff --git a/packages/vue/tsdown.config.ts b/packages/vue/tsdown.config.ts
new file mode 100644
index 00000000..7f0dfbd9
--- /dev/null
+++ b/packages/vue/tsdown.config.ts
@@ -0,0 +1,13 @@
+import { defineConfig } from "tsdown";
+
+export default defineConfig({
+ entry: ["src/index.ts"],
+ format: ["esm", "cjs"],
+ target: "es2021",
+ unbundle: true,
+ dts: true,
+ clean: true,
+ outDir: "dist",
+ tsconfig: "tsconfig.esm.json",
+ skipNodeModulesBundle: true,
+});
diff --git a/packages/vue/vitest.config.js b/packages/vue/vitest.config.js
new file mode 100644
index 00000000..cc93abb3
--- /dev/null
+++ b/packages/vue/vitest.config.js
@@ -0,0 +1,29 @@
+import { defineConfig } from "vitest/config";
+import path from "node:path";
+import { fileURLToPath } from "node:url";
+
+const __dirname = path.dirname(fileURLToPath(import.meta.url));
+
+export default defineConfig({
+ plugins: [],
+ resolve: {
+ alias: [
+ {
+ find: /^@ldo\/([^/]+)$/,
+ replacement: path.resolve(__dirname, "../$1/src/index.ts"),
+ },
+ {
+ find: /^@ldo\/([^/]+)\/(.*)$/,
+ replacement: path.resolve(__dirname, "../$1/$2"),
+ },
+ ],
+ },
+ test: {
+ globals: true,
+ setupFiles: ["../../vitest.jest-compat.ts"],
+ coverage: {
+ provider: "istanbul",
+ },
+ environment: "jsdom",
+ },
+});
diff --git a/tsconfig.base.json b/tsconfig.base.json
index ed5af721..abc54da4 100644
--- a/tsconfig.base.json
+++ b/tsconfig.base.json
@@ -2,7 +2,7 @@
"compilerOptions": {
"target": "ES2021",
"module": "commonjs",
- "lib": ["ES2021", "DOM"],
+ "lib": ["ES2021", "DOM", "DOM.Iterable"],
"strict": true,
"esModuleInterop": true,
"moduleResolution": "node",
diff --git a/vitest.jest-compat.ts b/vitest.jest-compat.ts
index 130a1690..4c9922e0 100644
--- a/vitest.jest-compat.ts
+++ b/vitest.jest-compat.ts
@@ -2,3 +2,24 @@ import { vi } from "vitest";
// Keep legacy Jest test helpers working during migration.
globalThis.jest = vi as unknown as Record;
+
+// vitest and jsdom don't play well together
+// browser and Node have different Uint8Array instances, leading to error in Jose library.
+// here, we loosen the instanceof Uint8Array check.
+if (typeof globalThis !== "undefined") {
+ // Keep Node's Uint8Array for reference
+ const NodeUint8Array = globalThis.__node_uint8array__ ?? Uint8Array;
+ globalThis.__node_uint8array__ ??= NodeUint8Array;
+
+ // overwrite the instanceof check with a more loose check so both instances pass the comparison
+ Object.defineProperty(NodeUint8Array, Symbol.hasInstance, {
+ value(instance: unknown) {
+ if (!instance) return false;
+ return (
+ instance.constructor?.name === "Uint8Array" ||
+ Object.prototype.toString.call(instance) === "[object Uint8Array]"
+ );
+ },
+ configurable: true,
+ });
+}