nitropage
Version:
A free and open source, extensible visual page builder based on SolidStart.
97 lines (87 loc) • 2.67 kB
text/typescript
import { createAsync, query } from "@solidjs/router";
import { Accessor, createMemo, useContext } from "solid-js";
import { Element } from "../../types";
import { NONE_BLUEPRINT_ID } from "../lib/constants";
import { ConfigContext, StateContext } from "../lib/context/page";
import { getElementData } from "../lib/elementData";
import {
getBlueprintDefaults as getBlueprintDefaults_,
getBlueprintPath as getBlueprintPath_,
} from "../lib/server/element/blueprint";
import { getPreset as getPreset_ } from "../lib/server/element/preset";
import { LOADING } from "../utils";
export const getPreset = query((id: string) => {
"use server";
return getPreset_(id);
}, "np-preset");
export const getBlueprintDefaults = query((id: string) => {
"use server";
return getBlueprintDefaults_(id);
}, "np-blueprintDefaults");
export const getBlueprintPath = query((id: string) => {
"use server";
return getBlueprintPath_(id);
}, "np-blueprintPath");
export const LAST_PROPERTY = "$$last";
export const useElementData = function (el: Accessor<Element>) {
const [declaration] = useContext(ConfigContext)!;
const [state] = useContext(StateContext)!;
const preset = createAsync(
async () =>
!state.admin && el().presetId
? await getPreset(el().presetId!)
: undefined,
{
deferStream: true,
initialValue: LOADING,
},
);
const defaults = createAsync(
async () =>
!state.admin && el().blueprintId && el().blueprintId !== NONE_BLUEPRINT_ID
? await getBlueprintDefaults(el().blueprintId!)
: undefined,
{ deferStream: true, initialValue: LOADING },
);
const loading = createMemo(
() => preset() === LOADING || defaults() === LOADING,
);
let lastProperty: string | undefined = undefined;
const proxy = new Proxy(
{},
{
ownKeys() {
const element = el();
const blueprint = element.blueprintId
? declaration.blueprints[element.blueprintId]
: undefined;
if (!blueprint) return [];
return Object.keys(blueprint.data);
},
getOwnPropertyDescriptor(target, prop) {
return {
enumerable: true,
configurable: true,
};
},
get(_, property: string) {
if (property === LAST_PROPERTY) {
return lastProperty;
}
lastProperty = property;
return getElementData(
el(),
state,
declaration,
property,
preset(),
defaults(),
);
},
set(_, property, value) {
return false;
},
},
);
return [proxy as any, loading] as const;
};