Skip to content

Commit

Permalink
Support specific ds library version and cache locally
Browse files Browse the repository at this point in the history
  • Loading branch information
dabbott committed Dec 15, 2023
1 parent 49df789 commit ceca333
Show file tree
Hide file tree
Showing 11 changed files with 153 additions and 34 deletions.
5 changes: 4 additions & 1 deletion packages/noya-compiler/src/__tests__/compile.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,10 @@ let ChakraDesignSystem: DesignSystemDefinition;
// let MaterialDesignSystem: DesignSystemDefinition;

beforeAll(async () => {
ChakraDesignSystem = await loadDesignSystem('chakra');
ChakraDesignSystem = await loadDesignSystem(
'@noya-design-system/chakra',
'latest',
);
// MaterialDesignSystem = await loadDesignSystem('mui');
});

Expand Down
2 changes: 1 addition & 1 deletion packages/noya-compiler/src/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,7 @@ export async function compileAsync(
await Promise.all(
configuration.definitions.map(async (name) => [
name,
await loadDesignSystem(name),
await loadDesignSystem(name, configuration.ds.source.version),
]),
),
);
Expand Down
50 changes: 41 additions & 9 deletions packages/noya-module-loader/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import fetch from 'cross-fetch';

import { DesignSystemDefinition } from '@noya-design-system/protocol';
import fetch from 'cross-fetch';
import { getKeyValueStore } from 'simple-kvs';
import { ThumbnailDesignSystem } from './ThumbnailDesignSystem';
import { VanillaDesignSystem } from './VanillaDesignSystem';
import { DesignSystemCache } from './cache';
Expand All @@ -22,14 +22,34 @@ function evaluateModule(content: string, Function: FunctionConstructor) {
return module.exports;
}

export async function loadModule(url: string, Function = window.Function) {
async function fetchModule(url: string) {
const response = await fetch(url);
const text = await response.text();
return evaluateModule(text, Function);
return text;
}

const UnpkgCache = {
getValue: async (key: string) => {
try {
const store = await getKeyValueStore('unpkg');
return await store.get<string>(key);
} catch (error) {
// ignore indexdb errors
}
},
setValue: async (key: string, value: string) => {
try {
const store = await getKeyValueStore('unpkg');
await store.set(key, value);
} catch (error) {
// ignore indexdb errors
}
},
};

export async function loadDesignSystem(
name: string,
version: string,
options: {
Function?: typeof window.Function;
enableCache?: boolean;
Expand All @@ -40,15 +60,27 @@ export async function loadDesignSystem(

const { Function = window.Function, enableCache = true } = options;

if (enableCache && DesignSystemCache.has(name)) {
return DesignSystemCache.get(name)!;
const key = `${name}@${version}`;

if (enableCache && DesignSystemCache.has(key)) {
return DesignSystemCache.get(key)!;
}

const url = name.includes('@')
? `https://www.unpkg.com/${name}/dist/standalone`
: `https://www.unpkg.com/@noya-design-system/${name}/dist/standalone`;
? `https://www.unpkg.com/${key}/dist/standalone`
: `https://www.unpkg.com/@noya-design-system/${key}/dist/standalone`;

let source = await UnpkgCache.getValue(url);

if (source === undefined) {
source = await fetchModule(url);

if (version !== 'latest') {
UnpkgCache.setValue(url, source);
}
}

const exports = await loadModule(url, Function);
const exports = evaluateModule(source, Function);

if (!(exports as any).DesignSystem) {
throw new Error('No DesignSystem exported');
Expand Down
1 change: 1 addition & 0 deletions packages/site/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"next": "^12",
"react-guidebook": "^0.13.0",
"react-resizable-panels": "^0.0.33",
"simple-kvs": "^0.1.2",
"vscode-fuzzy-scorer": "^0.0.4"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/site/src/ayon/components/DOMRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ const DOMRendererContent = memo(
<ErrorBoundary>
<DSControlledRenderer
ref={editingRef}
sourceName={ds.source.name}
librarySource={ds.source}
config={ds.config}
sync={sync}
setHighlightedPath={(path) => {
Expand Down
52 changes: 52 additions & 0 deletions packages/site/src/components/LibraryVersionPicker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Select } from 'noya-designsystem';
import React, { useMemo, useState } from 'react';

interface Props {
libraryName: string;
version: string;
onChange: (version: string) => void;
}

export function LibraryVersionPicker({
libraryName,
version,
onChange,
}: Props) {
const [availableVersions, setAvailableVersions] = useState<string[]>([]);

const options = useMemo(() => {
return [
...(!availableVersions.includes(version) ? [version] : []),
...availableVersions,
];
}, [availableVersions, version]);

useMemo(() => {
fetchAvailableVersions(libraryName).then(setAvailableVersions);
}, [libraryName]);

return (
<Select<string>
id="select-version"
value={version}
onChange={onChange}
options={options}
/>
);
}

async function fetchAvailableVersions(libraryName: string) {
const response = await fetch(`https://registry.npmjs.org/${libraryName}`);
const data = await response.json();
const versions = Object.keys(data.versions);

// Sort with newest versions first
versions.sort((a, b) => {
const aDate = new Date(data.time[a]);
const bDate = new Date(data.time[b]);

return bDate.getTime() - aDate.getTime();
});

return versions;
}
2 changes: 1 addition & 1 deletion packages/site/src/dseditor/DSControlledRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { SerializedSelection, closest } from './dom';
type Props = Pick<
ComponentProps<typeof DSRenderer>,
| 'config'
| 'sourceName'
| 'librarySource'
| 'renderContent'
| 'setHighlightedPath'
| 'setSelectedPath'
Expand Down
30 changes: 18 additions & 12 deletions packages/site/src/dseditor/DSEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,18 @@ export function DSEditor({
const [ds, setDS] = React.useState<DS>(initialDocument);
const project = useProject();

let {
source: { name: sourceName },
config,
components = initialComponents,
} = ds;

if (library) {
sourceName = library;
}
let { source, config, components = initialComponents } = ds;

const librarySource = useMemo(() => {
if (library) {
return {
...source,
name: library,
};
}

return source;
}, [library, source]);

const setComponents = useCallback((components: NoyaComponent[]) => {
setDS((ds) => ({
Expand Down Expand Up @@ -123,14 +126,17 @@ export function DSEditor({

useEffect(() => {
async function fetchLibrary() {
const system = await loadDesignSystem(sourceName);
const system = await loadDesignSystem(
librarySource.name,
librarySource.version,
);

setSystem(system);
}

setSystem(undefined);
fetchLibrary();
}, [sourceName]);
}, [librarySource]);

const [_selection, _setSelection] = React.useState<
Pick<SelectedComponent, 'diff' | 'variantID'>
Expand Down Expand Up @@ -501,7 +507,7 @@ export function DSEditor({
<Stack.V flex="1" overflow="hidden" position="relative">
<DSControlledRenderer
ref={rendererRef}
sourceName={sourceName}
librarySource={librarySource}
config={config}
renderContent={handleRenderContent}
getStringValueAtPath={getStringValueAtPath}
Expand Down
18 changes: 17 additions & 1 deletion packages/site/src/dseditor/DSProjectInspector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { uuid } from 'noya-utils';
import React, { useState } from 'react';
import { AyonListRow } from '../ayon/components/inspector/AyonListPrimitives';
import { InspectorSection } from '../components/InspectorSection';
import { LibraryVersionPicker } from '../components/LibraryVersionPicker';
import { downloadBlob } from '../utils/download';
import { DSThemeInspector } from './DSThemeInspector';

Expand Down Expand Up @@ -66,7 +67,7 @@ export function DSProjectInspector({
}: Props) {
const theme = useDesignSystemTheme();
const {
source: { name: sourceName },
source: { name: sourceName, version: sourceVersion },
} = ds;
const [renamingComponent, setRenamingComponent] = useState<
string | undefined
Expand Down Expand Up @@ -144,6 +145,21 @@ export function DSProjectInspector({
</Button>
</Select>
</InspectorPrimitives.LabeledRow>
{sourceName !== 'vanilla' && sourceName !== 'thumbnail' && (
<InspectorPrimitives.LabeledRow label="Library Version">
<LibraryVersionPicker
libraryName={sourceName}
version={sourceVersion}
onChange={(newVersion) => {
setDS((state) =>
produce(state, (draft) => {
draft.source.version = newVersion;
}),
);
}}
/>
</InspectorPrimitives.LabeledRow>
)}
<DSThemeInspector
dsConfig={ds.config}
onChangeDSConfig={(config) => {
Expand Down
20 changes: 12 additions & 8 deletions packages/site/src/dseditor/DSRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
component,
transform,
} from '@noya-design-system/protocol';
import { DSConfig } from 'noya-api';
import { DSConfig, DSSource } from 'noya-api';
import { Stack } from 'noya-designsystem';
import { Size } from 'noya-geometry';
import { loadDesignSystem } from 'noya-module-loader';
Expand Down Expand Up @@ -61,7 +61,7 @@ export interface IDSRenderer {
}

type Props = {
sourceName: string;
librarySource: DSSource;
config: DSConfig;
renderContent: (options: DSRenderProps) => React.ReactNode;
serializedSelection?: SerializedSelection;
Expand All @@ -76,7 +76,7 @@ type Props = {

export const DSRenderer = forwardRef(function DSRenderer(
{
sourceName,
librarySource,
config,
renderContent,
serializedSelection,
Expand Down Expand Up @@ -109,10 +109,14 @@ export const DSRenderer = forwardRef(function DSRenderer(
if (!ready) return;

async function fetchLibrary() {
const system = await loadDesignSystem(sourceName, {
Function: ref.current!.contentWindow!['Function' as any] as any,
enableCache: false,
});
const system = await loadDesignSystem(
librarySource.name,
librarySource.version,
{
Function: ref.current!.contentWindow!['Function' as any] as any,
enableCache: false,
},
);

if (!mounted) return;

Expand All @@ -125,7 +129,7 @@ export const DSRenderer = forwardRef(function DSRenderer(
return () => {
mounted = false;
};
}, [ready, sourceName]);
}, [ready, librarySource]);

useEffect(() => {
if (!system) {
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -19056,6 +19056,11 @@ simple-get@^3.0.3:
once "^1.3.1"
simple-concat "^1.0.0"

simple-kvs@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/simple-kvs/-/simple-kvs-0.1.2.tgz#d844375c7c732fb6e0d8da38ff7eda6921ea5f1d"
integrity sha512-KAUH2VeMUBQ7Mwq1R8gsK1KZZI6JNGy5NP0NqkY3pGekOuAM7i5VY9rxmcTHvIpA7hsXleEJpuqjUwxHAJE2xw==

sisteransi@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed"
Expand Down

0 comments on commit ceca333

Please sign in to comment.