Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- **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))
- **solid-vue:** Add Solid + Vue support with `@ldo/solid-vue` package. It provides `@ldo/vue` integration with Solid dataset and Solid auth session and additional Solid-specific Vue composables. ([#173](https://github.com/o-development/ldo/pull/173))

### Changed

Expand Down
4 changes: 4 additions & 0 deletions dev/solid-vue-vite-app/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# solid-vue-vite-app

Testing app for `@ldo/solid-vue`.

The rest of this file has been generated by `npm create vue@latest`.

This template should help get you started developing with Vue 3 in Vite.

## Recommended IDE Setup
Expand Down
21 changes: 21 additions & 0 deletions dev/solid-vue-vite-app/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { globalIgnores } from "eslint/config";
import {
defineConfigWithVueTs,
vueTsConfigs,
} from "@vue/eslint-config-typescript";
import pluginVue from "eslint-plugin-vue";

// To allow more languages other than `ts` in `.vue` files, uncomment the following lines:
// import { configureVueProject } from '@vue/eslint-config-typescript'
// configureVueProject({ scriptLangs: ['ts', 'tsx'] })
// More info at https://github.com/vuejs/eslint-config-typescript/#advanced-setup

export default defineConfigWithVueTs(
{
name: "app/files-to-lint",
files: ["**/*.{vue,ts,mts,tsx}"],
},
globalIgnores(["**/dist/**", "**/dist-ssr/**", "**/coverage/**"]),
...pluginVue.configs["flat/essential"],
vueTsConfigs.recommended,
);
11 changes: 9 additions & 2 deletions dev/solid-vue-vite-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,17 @@
"preview": "vite preview",
"build-only": "vite build",
"type-check": "vue-tsc --build",
"build:ldo": "ldo build --input src/_shapes --output src/_ldo"
"build:ldo": "ldo build --input src/_shapes --output src/_ldo",
"lint": "eslint ."
},
"dependencies": {
"@ldo/connected-nextgraph": "^1.0.0-alpha.50",
"@ldo/connected-solid": "^1.0.0-alpha.50",
"@ldo/ldo": "^1.0.0-alpha.50",
"@ldo/solid-vue": "^1.0.0-alpha.50",
"@ldo/vue": "^1.0.0-alpha.50",
"vue": "^3.5.40"
"vue": "^3.5.40",
"vue-router": "^5.4.0"
},
"devDependencies": {
"@ldo/cli": "^1.0.0-alpha.50",
Expand All @@ -24,7 +28,10 @@
"@types/node": "^24.13.3",
"@types/shexj": "^2.1.7",
"@vitejs/plugin-vue": "^6.0.8",
"@vue/eslint-config-typescript": "^14.9.0",
"@vue/tsconfig": "^0.9.1",
"eslint": "^10.12.0",
"eslint-plugin-vue": "^10.11.1",
"npm-run-all2": "^9.0.2",
"typescript": "~6.0.0",
"vite": "^8.1.5",
Expand Down
103 changes: 49 additions & 54 deletions dev/solid-vue-vite-app/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,61 +1,56 @@
<script setup lang="ts">
import { computed, ref } from "vue";
import { FoafProfileShapeType } from "./_ldo/foafProfile.shapeTypes.js";
import { useSubject, useResource } from "./ldo.js";
import UseMatchSubjectTest from "./useMatchSubjectTest.vue";
import VueReadmeTest from "./vueReadmeTest.vue";

const isValidUrl = (str: string) => {
try {
return Boolean(new URL(str));
} catch {
return false;
}
};

const inputUri = ref("");
import { provideSolidLdo } from "./ldo";
import { RouterView, RouterLink } from "vue-router";
import SolidAuth from "./UseSolidAuth.vue";

const validUri = computed(() =>
isValidUrl(inputUri.value) ? inputUri.value : "",
);

const subject = useSubject(FoafProfileShapeType, inputUri);
console.log(subject);
useResource(validUri);
provideSolidLdo();
</script>

<template>
<div>
<h1>vue Solid auth test</h1>
<input v-model="inputUri" placeholder="enter webId" />
<div>{{ subject?.name ?? subject?.["@id"] }}</div>
<ul>
<li v-for="friend in subject?.knows" :key="friend['@id']">
{{ friend["@id"] }}
</li>
</ul>

<p>checked:</p>
<p>active:</p>
<p>webId:</p>
<p>webId resource:</p>

<form>
<input />
<button type="submit">login</button>
</form>

<!-- <button type="button" @onClick="logout">logout</button> -->

<form>
<input />
<button type="submit">fetch</button>
</form>

<pre></pre>
</div>
<UseMatchSubjectTest />
<VueReadmeTest />
<header class="header">
<nav class="navigation">
<RouterLink to="/">home</RouterLink>
<RouterLink to="/use-resource">useResource</RouterLink>
<RouterLink to="/use-solid-auth">useSolidAuth</RouterLink>
<RouterLink to="/use-match-subject">useMatchSubject</RouterLink>
<RouterLink to="/use-root-container-for">useRootContainerFor</RouterLink>
</nav>

<div class="auth">
<SolidAuth />
</div>
</header>

<main>
<RouterView />
</main>
</template>

<style scoped></style>
<style scoped lang="css">
.header {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
margin: 1rem;
}

.navigation,
.auth {
display: flex;
gap: 1rem;
flex-wrap: wrap;
}

.navigation {
a {
text-decoration: none;
font-variant: small-caps;
cursor: pointer;

&.router-link-exact-active {
color: red;
}
}
}
</style>
55 changes: 55 additions & 0 deletions dev/solid-vue-vite-app/src/LandingPage.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<script setup lang="ts">
import { computed, ref } from "vue";
import { FoafProfileShapeType } from "./_ldo/foafProfile.shapeTypes";
import { useSubject, useResource } from "./ldo";
import VueReadmeTest from "./VueReadmeTest.vue";

const isValidUrl = (str: string) => {
try {
return Boolean(new URL(str));
} catch {
return false;
}
};

const inputUri = ref("");

const validUri = computed(() =>
isValidUrl(inputUri.value) ? inputUri.value : "",
);

const subject = useSubject(FoafProfileShapeType, inputUri);
useResource(validUri);
</script>

<template>
<div>
<input v-model="inputUri" placeholder="enter webId" />
<div>{{ subject?.name ?? subject?.["@id"] }}</div>
<ul>
<li v-for="friend in subject?.knows" :key="friend['@id']">
{{ friend["@id"] }}
</li>
</ul>

<p>checked:</p>
<p>active:</p>
<p>webId:</p>
<p>webId resource:</p>

<form>
<input />
<button type="submit">login</button>
</form>

<!-- <button type="button" @onClick="logout">logout</button> -->

<form>
<input />
<button type="submit">fetch</button>
</form>

<pre></pre>
</div>
<VueReadmeTest />
</template>
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
<script setup lang="ts">
import { computed, ref } from "vue";
import { FoafProfileShapeType } from "./_ldo/foafProfile.shapeTypes.js";
import { useResource, useMatchSubject } from "./ldo.js";
import type { FoafProfile } from "./_ldo/foafProfile.typings.js";
import { FoafProfileShapeType } from "./_ldo/foafProfile.shapeTypes";
import { useResource, useMatchSubject } from "./ldo";

const isValidUrl = (str: string) => {
try {
Expand All @@ -19,7 +18,7 @@ const graphInput = ref("");

const predicate = computed(() => predicateInput.value || undefined);
const object = computed(() => objectInput.value || undefined);
const graph = computed(() => graphInput.value || resource.value);
const graph = computed(() => graphInput.value || undefined);

const validResource = computed(() =>
isValidUrl(resource.value) ? resource.value : "",
Expand All @@ -32,29 +31,35 @@ const subjectsSet = useMatchSubject(
graph,
);

// const subjects = computed(() => {
// return subjectsSet.value.toArray();
// });

useResource(validResource);
</script>

<template>
<div>
<h1>useMatchSubject test</h1>
<h2>useMatchSubject</h2>
<div>
<label for="resource">load resource: </label>
<input id="resource" v-model="resource" placeholder="resource" />
</div>

<input v-model="resource" placeholder="resource" />
<br />
<input v-model="predicateInput" placeholder="predicate" />
<br />
<input v-model="objectInput" placeholder="object" />
<br />
<input v-model="graphInput" placeholder="graph" />
<br />

<div>
<input v-model="predicateInput" placeholder="predicate" />
<br />
<input v-model="objectInput" placeholder="object" />
<br />
<input v-model="graphInput" placeholder="graph" />
</div>

<ul>
<li v-for="item in subjectsSet">
{{ item.knows?.map((p: FoafProfile) => p["@id"]).join(", ") }}
<li v-for="item in subjectsSet" v-bind:key="item['@id']">
{{ item.name ?? item["@id"] }}:
<ul>
<li v-for="friend in item.knows" v-bind:key="friend['@id']">
{{ friend.name ?? friend["@id"] }}
</li>
</ul>
</li>
</ul>
</div>
Expand Down
74 changes: 74 additions & 0 deletions dev/solid-vue-vite-app/src/UseResource.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<script setup lang="ts">
import { computed, ref, triggerRef } from "vue";
import { useResource } from "./ldo";
import type { SolidContainerUri, SolidLeafUri } from "@ldo/connected-solid";
import type { UseResourceOptions } from "@ldo/vue";

const uri = ref<SolidLeafUri | SolidContainerUri>(
"https://timbl.solidcommunity.net/profile/",
);
const subscribe = ref(false);
const reloadOnMount = ref(false);
const suppressInitialRead = ref(true);

const options = computed<UseResourceOptions<"solid">>(() => ({
subscribe: subscribe.value,
reloadOnMount: reloadOnMount.value,
suppressInitialRead: suppressInitialRead.value,
}));

const resource = useResource(uri, options);

const handleReadManually = async () => {
await resource.value.read();
};

const handleRefresh = () => {
triggerRef(resource);
};
</script>

<template>
<h2>useResource</h2>

<div class="controls">
<label>uri: <input v-model="uri" placeholder="uri" size="50" /></label>
<button @click="handleReadManually">read manually</button>
<button @click="handleRefresh">refresh resource results</button>
<label
><input v-model="suppressInitialRead" type="checkbox" />
suppressInitialRead</label
>
<label
><input v-model="reloadOnMount" type="checkbox" /> reloadOnMount</label
>
<label><input type="checkbox" v-model="subscribe" /> subscribe</label>
</div>

<div class="results" v-if="resource">
<div>uri: {{ resource.uri }}</div>
<div>isDoingInitialFetch: {{ resource.isDoingInitialFetch() }}</div>
<div>isLoading: {{ resource.isLoading() }}</div>
<div>isReloading: {{ resource.isReloading() }}</div>
<div>isFetched: {{ resource.isFetched() }}</div>
<div>isUnfetched: {{ resource.isUnfetched() }}</div>
<div>isAbsent: {{ resource.isAbsent() }}</div>
<div>isPresent: {{ resource.isPresent() }}</div>
<div>status: {{ resource.status.type }}</div>
<div>
isSubscribedToNotifications: {{ resource.isSubscribedToNotifications() }}
</div>
<div>{{ (resource as any).notificationSubscription.subscriptions }}</div>
<div></div>
</div>
</template>

<style scoped lang="css">
.controls {
display: flex;
flex-direction: column;
gap: 0.5rem;
align-items: flex-start;
margin-bottom: 2rem;
}
</style>
Loading
Loading