Skip to content

Commit

Permalink
Refactor @tomic/svelte to Svelte 5 and update sveltekit-site template
Browse files Browse the repository at this point in the history
  • Loading branch information
Polleps authored and joepio committed Nov 11, 2024
1 parent 69492b6 commit 199e1e8
Show file tree
Hide file tree
Showing 66 changed files with 1,253 additions and 1,298 deletions.
22 changes: 22 additions & 0 deletions browser/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,31 @@ This changelog covers all five packages, as they are (for now) updated as a whol
- [#992](https://github.com/atomicdata-dev/atomic-server/issues/992) Fix Searchbox overflowing when displaying long names.
- [#999](https://github.com/atomicdata-dev/atomic-server/issues/999) Fix parseMetaTags character escape issue.

### @tomic/lib

- `resource.props` is now writable: `resource.props.name = 'New Name'`.
- Added `store.preloadResourceTree()` method.
- Fix generated ontologies not working in a Next.js server context.

### @tomic/cli

- [#983](https://github.com/atomicdata-dev/atomic-server/issues/983) Give clear error when name collisions are found in an ontology.
- Generates class definitions that enables doing: `resource.props.name = 'New Name'`;

### @tomic/svelte

- [#700](https://github.com/atomicdata-dev/atomic-server/issues/700) Update to Svelte 5. There are significant changes to the API.
- BREAKING CHANGE: Dropped support for Svelte 4 and below.
- BREAKING CHANGE: `getResource()` now returns a reactive proxy instead of a readable store.
- BREAKING CHANGE: `getResource()` now takes a function returning a subject instead of the subject directly. e.g. `getResource(() => 'https://my-atomicserver.com/my-resource');`.
- BREAKING CHANGE: Removed `getValue()`. It is no longer needed. Instead use `resource.props.name` directly or do `const name = $derived(resource.get(core.properties.name));`.
- BREAKING CHANGE: Removed `initStore()`. You now need to set your store on a context using `createAtomicStoreContext()`.
- BREAKING CHANGE: Removed `loadResourceTree()`. It is now a method on `store`: `store.preloadResourceTree()`.
- Added `createAtomicStoreContext()` and `getStoreFromContext()`.

### @tomic/create-template

- [#700](https://github.com/atomicdata-dev/atomic-server/issues/700) Update SvelteKit-site template to Svelte 5.

## [v0.40.0] - 2024-10-07

Expand Down
36 changes: 34 additions & 2 deletions browser/cli/src/generateBaseObject.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Resource, type Core } from '@tomic/lib';
import { Resource, type Core, core } from '@tomic/lib';
import { store } from './store.js';
import { camelCaseify, dedupe } from './utils.js';
import chalk from 'chalk';
Expand All @@ -8,6 +8,7 @@ export type ReverseMapping = Record<string, string>;
type BaseObject = {
classes: Record<string, string>;
properties: Record<string, string>;
__classDefs: Record<string, string[]>;
};

export const generateBaseObject = async (
Expand All @@ -24,12 +25,14 @@ export const generateBaseObject = async (
const baseObj = {
classes: await listToObj(classes, 'classes'),
properties: await listToObj(properties, 'properties'),
__classDefs: await createClassDefs(classes),
};

const objStr = `export const ${name} = {
classes: ${recordToString(baseObj.classes)},
properties: ${recordToString(baseObj.properties)},
} as const`;
__classDefs: ${stringifyClassDefs(baseObj.__classDefs)}
} as const satisfies OntologyBaseObject`;

return [objStr, createReverseMapping(name, baseObj)];
};
Expand Down Expand Up @@ -71,6 +74,26 @@ const listToObj = async (
return Object.fromEntries(entries);
};

const createClassDefs = async (
classes: string[],
): Promise<Record<string, string[]>> => {
const classResources = await Promise.all(
classes.map(async c => await store.getResource(c)),
);

const entries = classResources.map(resource => {
return [
resource.subject,
[
...resource.getArray(core.properties.requires),
...resource.getArray(core.properties.recommends),
],
];
});

return Object.fromEntries(entries);
};

const recordToString = (obj: Record<string, string>): string => {
const innerSting = Object.entries(obj).reduce(
(acc, [key, value]) => `${acc}\n\t${key}: '${value}',`,
Expand All @@ -80,6 +103,15 @@ const recordToString = (obj: Record<string, string>): string => {
return `{${innerSting}\n }`;
};

const stringifyClassDefs = (obj: Record<string, string[]>) => {
const innerString = Object.entries(obj).reduce(
(acc, [key, value]) => `${acc}\n\t["${key}"]: ${JSON.stringify(value)},`,
'',
);

return `{${innerString}\n }`;
};

const createReverseMapping = (
ontologyTitle: string,
obj: BaseObject,
Expand Down
2 changes: 1 addition & 1 deletion browser/cli/src/generateOntology.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const TEMPLATE = `
* For more info on how to use ontologies: https://github.com/atomicdata-dev/atomic-server/blob/develop/browser/cli/readme.md
* -------------------------------- */
import type { BaseProps } from '${Inserts.MODULE_ALIAS}'
import type { OntologyBaseObject, BaseProps } from '${Inserts.MODULE_ALIAS}'
${Inserts.BASE_OBJECT}
Expand Down
2 changes: 2 additions & 0 deletions browser/create-template/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
/bin

/templates/**/ontologies/**/*
16 changes: 8 additions & 8 deletions browser/create-template/templates/sveltekit-site/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
"update-ontologies": "ad-generate ontologies"
},
"devDependencies": {
"@sveltejs/adapter-auto": "^3.3.0",
"@sveltejs/adapter-node": "^5.2.8",
"@sveltejs/kit": "^2.7.2",
"@sveltejs/vite-plugin-svelte": "^3.1.2",
"@sveltejs/adapter-auto": "^3.3.1",
"@sveltejs/adapter-node": "^5.2.9",
"@sveltejs/kit": "^2.7.3",
"@sveltejs/vite-plugin-svelte": "^4.0.0-next.6",
"@tomic/cli": "^0.39.0",
"@types/eslint": "^9.6.1",
"eslint": "^9.13.0",
Expand All @@ -26,17 +26,17 @@
"globals": "^15.11.0",
"prettier": "^3.3.3",
"prettier-plugin-svelte": "^3.2.7",
"svelte": "^4.2.19",
"svelte-check": "^3.8.6",
"svelte": "^5.1.4",
"svelte-check": "^4.0.5",
"typescript": "^5.6.3",
"typescript-eslint": "^8.11.0",
"vite": "^5.4.10",
"vitest": "^2.1.3"
},
"type": "module",
"dependencies": {
"@tomic/lib": "^0.39.0",
"@tomic/svelte": "^0.39.0",
"@tomic/lib": "^0.40.0",
"@tomic/svelte": "^0.40.0",
"svelte-markdown": "^0.4.1"
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { website } from '$lib/ontologies/website';
import { CollectionBuilder, core } from '@tomic/lib';
import { store as storeStore } from '@tomic/svelte';
import { get } from 'svelte/store';
import { getStore } from './getStore';
export async function getAllBlogposts(): Promise<string[]> {
const store = get(storeStore);
const store = getStore();

const collection = new CollectionBuilder(store)
.setProperty(core.properties.isA)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,9 @@ export async function getCurrentResource(

const currentResourceSubject = await collection.getMemberWithIndex(0);

if (currentResourceSubject === undefined) {
return undefined;
}

return await store.getResource(currentResourceSubject);
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
import { get } from 'svelte/store';
import { initStore, store as atomicStore } from '@tomic/svelte';
import { Store } from '@tomic/lib';
import { PUBLIC_ATOMIC_SERVER_URL } from '$env/static/public';
import { initOntologies } from '$lib/ontologies';

// We use a global store. Keep in mind that this means the cache is shared between sessions. Don't do this if you have data that should only be available to certain agents.
let store: Store | undefined;

const init = () => {
const atomicStore = new Store({
store = new Store({
serverUrl: PUBLIC_ATOMIC_SERVER_URL
});
initStore(atomicStore);

initOntologies();
};

export const getStore = () => {
let store = get(atomicStore);

export const getStore = (): Store => {
if (store === undefined) {
init();
store = get(atomicStore);
}

return store;
return store!;
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { website } from '$lib/ontologies/website';
import type { Resource } from '@tomic/lib';
import { loadResourceTree } from '@tomic/svelte';
import { getStore } from './getStore';

/**
* Due to how sveltekit works we sometimes need to preload resources for them to show up in the serverside rendered html.
Expand All @@ -9,16 +9,26 @@ import { loadResourceTree } from '@tomic/svelte';
* If you do not preload the referenced resources they will not show up when the page is hydrated client side. This should not be a big problem but could cause issues with SEO or users that have javascript disabled.
*/
export async function preloadResources(resource: Resource): Promise<void> {
const store = getStore();

if (resource.hasClasses(website.classes.website)) {
await store.preloadResourceTree(resource.subject, {
[website.properties.menuItems]: {
[website.properties.subItems]: true
}
});
}

if (resource.hasClasses(website.classes.page)) {
await loadResourceTree(resource.subject, {
await store.preloadResourceTree(resource.subject, {
[website.properties.blocks]: {
[website.properties.images]: true
}
});
}

if (resource.hasClasses(website.classes.blogpost)) {
await loadResourceTree(resource.subject, {
await store.preloadResourceTree(resource.subject, {
[website.properties.coverImage]: true
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@
align-items: var(--hstack-align);
justify-content: var(--hstack-justify);
& > h1,
& > h2,
& > h3,
& > h4,
& > h5,
& > h6 {
:global(& > h1),
:global(& > h2),
:global(& > h3),
:global(& > h4),
:global(& > h5),
:global(& > h6) {
margin: 0;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@
justify-content: var(--vstack-justify);
height: var(--vstack-height);
min-height: var(--vstack-min-height);
& > h1,
& > h2,
& > h3,
& > h4,
& > h5,
& > h6 {
:global(& > h1),
:global(& > h2),
:global(& > h3),
:global(& > h4),
:global(& > h5),
:global(& > h6) {
margin: 0;
}
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,30 +1,28 @@
<script lang="ts">
import { PUBLIC_WEBSITE_RESOURCE } from '$env/static/public';
import { type Website } from '$lib/ontologies/website';
import { website, type Website } from '$lib/ontologies/website';
import { getResource } from '@tomic/svelte';
import MenuItem from '../views/MenuItem/MenuItem.svelte';
import Container from './Layout/Container.svelte';
import HStack from './Layout/HStack.svelte';
import Loader from './Loader.svelte';
$: site = getResource<Website>(PUBLIC_WEBSITE_RESOURCE);
let site = getResource<Website>(() => PUBLIC_WEBSITE_RESOURCE);
let menuItems = $derived(site.props.menuItems ?? []);
</script>

<Container>
<nav>
<HStack align="center" justify="space-between" wrap>
<Loader resource={$site}>
<a class="site-title" href="/">
{$site.title}
</a>
<ul>
{#each $site.props.menuItems ?? [] as menuItem}
<li>
<MenuItem subject={menuItem} />
</li>
{/each}
</ul>
</Loader>
<a class="site-title" href="/">
{site.title}
</a>
<ul>
{#each menuItems as menuItem (menuItem)}
<li>
<MenuItem subject={menuItem} />
</li>
{/each}
</ul>
</HStack>
</nav>
</Container>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,24 @@
import FaMagnifyingGlass from './Icons/FaMagnifyingGlass.svelte';
import HStack from './Layout/HStack.svelte';
export let value: string;
export let placeholder: string = 'Search...';
interface Props {
value?: string;
placeholder: string;
oninput: (value: string) => void;
}
let { value = $bindable(''), placeholder, oninput }: Props = $props();
</script>

<div class="search-bar">
<HStack align="center" gap="1ch">
<FaMagnifyingGlass />
<input type="search" bind:value {placeholder} />
<input
type="search"
bind:value
{placeholder}
oninput={(e) => oninput(e.currentTarget.value ?? '')}
/>
</HStack>
</div>

Expand All @@ -22,7 +32,7 @@
&:focus-within {
box-shadow: 0px 0px 0px 2px var(--theme-color-accent);
}
& svg {
:global(& svg) {
width: 1rem;
fill: var(--theme-color-text-light);
}
Expand Down
Loading

0 comments on commit 199e1e8

Please sign in to comment.