From 40540c9a11236a55c3d32a597e7e13c6536571d9 Mon Sep 17 00:00:00 2001 From: Harlan Wilton Date: Mon, 22 Aug 2022 17:04:19 +1000 Subject: [PATCH] feat(core): improve createSchemaOrg API - add forceRefresh method - allow promises for meta resolution - rename client to SchemaOrgVuePlugin --- .../runtime/composables/injectSchemaOrg.ts | 6 +- .../runtime/composables/useSchemaOrg.ts | 8 +- .../src/composables/createSchemaOrg.ts | 104 +++++++++--------- 3 files changed, 59 insertions(+), 59 deletions(-) diff --git a/packages/schema-org/runtime/composables/injectSchemaOrg.ts b/packages/schema-org/runtime/composables/injectSchemaOrg.ts index 799526e..35ba033 100644 --- a/packages/schema-org/runtime/composables/injectSchemaOrg.ts +++ b/packages/schema-org/runtime/composables/injectSchemaOrg.ts @@ -1,11 +1,11 @@ import { PROVIDE_KEY } from '@vueuse/schema-org' -import type { SchemaOrgClient } from '@vueuse/schema-org' +import type { SchemaOrgVuePlugin } from '@vueuse/schema-org' import { inject } from 'vue' export function injectSchemaOrg() { - let client: SchemaOrgClient | undefined + let client: SchemaOrgVuePlugin | undefined try { - client = inject(PROVIDE_KEY) + client = inject(PROVIDE_KEY) } catch (e) {} diff --git a/packages/schema-org/runtime/composables/useSchemaOrg.ts b/packages/schema-org/runtime/composables/useSchemaOrg.ts index ab4a558..b889cfb 100644 --- a/packages/schema-org/runtime/composables/useSchemaOrg.ts +++ b/packages/schema-org/runtime/composables/useSchemaOrg.ts @@ -19,9 +19,8 @@ export function useSchemaOrg(input: any) { // SSR Mode does not need to do anything else. if (typeof window === 'undefined') { nextTick(() => { - watch(() => input, () => { - client.generateSchema() - client.setupDOM() + watch(() => input, async () => { + await client.forceRefresh() }, { immediate: true, deep: true, @@ -40,8 +39,7 @@ export function useSchemaOrg(input: any) { // CSR Mode will need to manually trigger the schema to re-generate onMounted(() => { - client.generateSchema() - client.setupDOM() + client.forceRefresh() }) onBeforeUnmount(() => { diff --git a/packages/schema-org/src/composables/createSchemaOrg.ts b/packages/schema-org/src/composables/createSchemaOrg.ts index 1209493..e5f2d16 100644 --- a/packages/schema-org/src/composables/createSchemaOrg.ts +++ b/packages/schema-org/src/composables/createSchemaOrg.ts @@ -6,27 +6,27 @@ import type { } from 'schema-org-graph-js' import { buildResolvedGraphCtx, - createSchemaOrgGraph, dedupeAndFlattenNodes, renderNodesToSchemaOrgHtml, resolveMeta, + createSchemaOrgGraph, organiseNodes, renderNodesToSchemaOrgHtml, resolveMeta, } from 'schema-org-graph-js' export interface CreateSchemaOrgInput { /** * The meta data used to render the final schema.org graph. */ - meta: () => MetaInput + meta: () => MetaInput | Promise /** * Client used to write schema to the document. */ - updateHead: (fn: ComputedRef) => void - /** - * Will enable debug logs to be shown. - */ - debug?: boolean + updateHead: (fn: ComputedRef) => void | Promise } -export interface SchemaOrgClient { +export interface SchemaOrgVuePlugin { + /** + * Install the plugin on the Vue context. + * + * @param app + */ install: (app: App) => void - /** * Given a Vue component context, deleted any nodes associated with it. */ @@ -34,17 +34,22 @@ export interface SchemaOrgClient { /** * Sets up the initial placeholder for the meta tag using useHead. */ - setupDOM: () => void - + setupDOM: () => void | Promise /** * Trigger the schemaRef to be updated. */ - generateSchema: () => Ref - resolveGraph: () => SchemaOrgContext - resolvedSchemaOrg: () => string - - schemaRef: Ref + generateSchema: () => Promise> | Ref + /** + * Force Schema.org to be refreshed in the DOM. + */ + forceRefresh: () => Promise + /** + * The inner context being used to generate the Schema.org graph. + */ ctx: SchemaOrgContext + /** + * Options used to render the Schema. + */ options: CreateSchemaOrgInput } @@ -54,39 +59,38 @@ const unrefDeep = (n: any) => { return n } -export const PROVIDE_KEY = Symbol('schemaorg') as InjectionKey +export const PROVIDE_KEY = Symbol('schemaorg') as InjectionKey export const createSchemaOrg = (options: CreateSchemaOrgInput) => { const schemaRef = ref('') let ctx = createSchemaOrgGraph() - const client: SchemaOrgClient = { - install(app) { - app.config.globalProperties.$schemaOrg = client - app.provide(PROVIDE_KEY, client) - }, + const resolveGraphNodesToHtml = async () => { + const meta = await options.meta() + const resolvedMeta = resolveMeta(unrefDeep(meta)) + const resolvedCtx = buildResolvedGraphCtx(ctx.nodes.map(unrefDeep), resolvedMeta) + const nodes = organiseNodes(resolvedCtx.nodes) + return renderNodesToSchemaOrgHtml(nodes) + } + const client: SchemaOrgVuePlugin = { ctx, options, - schemaRef, - resolveGraph() { - const meta = resolveMeta(unrefDeep(options.meta())) - if (!meta.host) - console.warn('[WARN] `@vueuse/schema-org`: Missing required `host` from `createSchemaOrg`.') - return buildResolvedGraphCtx(ctx.nodes.map(unrefDeep), meta) + install(app) { + app.config.globalProperties.$schemaOrg = client + app.provide(PROVIDE_KEY, client) }, - resolvedSchemaOrg() { - const resolvedCtx = client.resolveGraph() - const nodes = dedupeAndFlattenNodes(resolvedCtx.nodes) - return renderNodesToSchemaOrgHtml(nodes) + async generateSchema() { + schemaRef.value = await resolveGraphNodesToHtml() + return schemaRef }, - generateSchema() { - schemaRef.value = client.resolvedSchemaOrg() - return schemaRef + async forceRefresh() { + await client.generateSchema() + await client.setupDOM() }, removeContext(uid) { @@ -97,22 +101,20 @@ export const createSchemaOrg = (options: CreateSchemaOrgInput) => { }, setupDOM() { - if (options?.updateHead) { - options.updateHead(computed(() => { - return { - // Can be static or computed - script: [ - { - 'type': 'application/ld+json', - 'data-id': 'schema-org-graph', - 'key': 'schema-org-graph', - 'children': schemaRef.value, - 'body': true, - }, - ], - } - })) - } + return options.updateHead(computed(() => { + return { + // Can be static or computed + script: [ + { + 'type': 'application/ld+json', + 'data-id': 'schema-org-graph', + 'key': 'schema-org-graph', + 'children': schemaRef.value, + 'body': true, + }, + ], + } + })) }, } return client