dtwo 3.1.2 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/app/components/dtwo-error-boundary.mjs +1 -1
  2. package/dist/app/components/dtwo-island.mjs +3 -1
  3. package/dist/app/components/dtwo-loading-indicator.mjs +1 -1
  4. package/dist/app/components/dtwo-root.kdu +3 -1
  5. package/dist/app/components/island-renderer.mjs +1 -1
  6. package/dist/app/components/layout.mjs +1 -1
  7. package/dist/app/composables/component.mjs +1 -1
  8. package/dist/app/composables/fetch.d.ts +7 -6
  9. package/dist/app/composables/fetch.mjs +7 -1
  10. package/dist/app/composables/head.d.ts +2 -0
  11. package/dist/app/composables/head.mjs +1 -0
  12. package/dist/app/composables/index.d.ts +3 -1
  13. package/dist/app/composables/index.mjs +2 -1
  14. package/dist/app/composables/payload.mjs +2 -2
  15. package/dist/app/composables/preload.mjs +1 -1
  16. package/dist/app/composables/ssr.d.ts +1 -0
  17. package/dist/app/composables/ssr.mjs +7 -0
  18. package/dist/app/entry-spa.d.ts +2 -0
  19. package/dist/app/entry-spa.mjs +2 -0
  20. package/dist/app/entry.mjs +1 -1
  21. package/dist/app/index.d.ts +0 -2
  22. package/dist/app/index.mjs +0 -1
  23. package/dist/app/plugins/cross-origin-prefetch.client.mjs +2 -1
  24. package/dist/app/plugins/debug.mjs +1 -1
  25. package/dist/app/plugins/payload.client.mjs +3 -1
  26. package/dist/app/plugins/preload.server.mjs +1 -1
  27. package/dist/app/plugins/router.d.ts +1 -1
  28. package/dist/app/plugins/router.mjs +5 -1
  29. package/dist/components/runtime/server-component.mjs +4 -1
  30. package/dist/head/runtime/composables.mjs +1 -1
  31. package/dist/head/runtime/lib/kduse-head.plugin.mjs +1 -1
  32. package/dist/index.mjs +171 -56
  33. package/dist/pages/runtime/page.mjs +1 -1
  34. package/dist/pages/runtime/plugins/prefetch.client.mjs +2 -1
  35. package/dist/pages/runtime/plugins/router.mjs +5 -1
  36. package/dist/pages/runtime/router.options.mjs +1 -1
  37. package/dist/pages/runtime/validate.mjs +1 -1
  38. package/package.json +17 -18
@@ -1,5 +1,5 @@
1
1
  import { defineComponent, ref, onErrorCaptured } from "kdu";
2
- import { useDtwoApp } from "#app";
2
+ import { useDtwoApp } from "#app/dtwo";
3
3
  export default defineComponent({
4
4
  emits: {
5
5
  error(_error) {
@@ -2,7 +2,9 @@ import { defineComponent, createStaticKNode, computed, ref, watch } from "kdu";
2
2
  import { debounce } from "perfect-debounce";
3
3
  import { hash } from "ohash";
4
4
  import { appendHeader } from "h3";
5
- import { useHead, useDtwoApp, useRequestEvent } from "#app";
5
+ import { useDtwoApp } from "#app/dtwo";
6
+ import { useRequestEvent } from "#app/composables/ssr";
7
+ import { useHead } from "#app/composables/head";
6
8
  const pKey = "_islandPromises";
7
9
  export default defineComponent({
8
10
  name: "DtwoIsland",
@@ -1,5 +1,5 @@
1
1
  import { computed, defineComponent, h, onBeforeUnmount, ref } from "kdu";
2
- import { useDtwoApp } from "#app";
2
+ import { useDtwoApp } from "#app/dtwo";
3
3
  export default defineComponent({
4
4
  name: "DtwoLoadingIndicator",
5
5
  props: {
@@ -8,7 +8,9 @@
8
8
 
9
9
  <script setup>
10
10
  import { defineAsyncComponent, onErrorCaptured, onServerPrefetch, provide } from 'kdu'
11
- import { callWithDtwo, isDtwoError, showError, useError, useRoute, useDtwoApp } from '#app'
11
+ import { callWithDtwo, useDtwoApp } from '#app/dtwo'
12
+ import { isDtwoError, showError, useError } from '#app/composables/error'
13
+ import { useRoute } from '#app/composables/router'
12
14
  import AppComponent from '#build/app-component.mjs'
13
15
 
14
16
  const ErrorComponent = defineAsyncComponent(() => import('#build/error-component.mjs').then(r => r.default || r))
@@ -1,6 +1,6 @@
1
1
  import { createBlock, defineComponent, h, Teleport } from "kdu";
2
2
  import * as islandComponents from "#build/components.islands.mjs";
3
- import { createError } from "#app";
3
+ import { createError } from "#app/composables/error";
4
4
  export default defineComponent({
5
5
  props: {
6
6
  context: {
@@ -1,6 +1,6 @@
1
1
  import { computed, defineComponent, h, inject, nextTick, onMounted, Transition, unref } from "kdu";
2
2
  import { _wrapIf } from "./utils.mjs";
3
- import { useRoute } from "#app";
3
+ import { useRoute } from "#app/composables/router";
4
4
  import { useRoute as useKduRouterRoute } from "#build/pages";
5
5
  import layouts from "#build/layouts";
6
6
  import { appLayoutTransition as defaultLayoutTransition } from "#build/dtwo.config.mjs";
@@ -2,7 +2,7 @@ import { getCurrentInstance, reactive, toRefs } from "kdu";
2
2
  import { useDtwoApp } from "../dtwo.mjs";
3
3
  import { useAsyncData } from "./asyncData.mjs";
4
4
  import { useRoute } from "./router.mjs";
5
- import { useHead } from "#head";
5
+ import { useHead } from "./head.mjs";
6
6
  export const DtwoComponentIndicator = "__dtwo_component";
7
7
  async function runLegacyAsyncData(res, fn) {
8
8
  const dtwo = useDtwoApp();
@@ -1,15 +1,16 @@
1
1
  import type { FetchError } from 'ofetch';
2
- import type { TypedInternalResponse, HoleFetchOptions, HoleFetchRequest } from 'holepack';
2
+ import type { TypedInternalResponse, HoleFetchOptions, HoleFetchRequest, AvailableRouterMethod } from 'holepack';
3
3
  import type { Ref } from 'kdu';
4
4
  import type { AsyncDataOptions, _Transform, KeyOfRes, AsyncData, PickFrom } from './asyncData';
5
- export type FetchResult<ReqT extends HoleFetchRequest> = TypedInternalResponse<ReqT, unknown>;
5
+ export type FetchResult<ReqT extends HoleFetchRequest, M extends AvailableRouterMethod<ReqT>> = TypedInternalResponse<ReqT, unknown, M>;
6
6
  type ComputedOptions<T extends Record<string, any>> = {
7
7
  [K in keyof T]: T[K] extends Function ? T[K] : T[K] extends Record<string, any> ? ComputedOptions<T[K]> | Ref<T[K]> | T[K] : Ref<T[K]> | T[K];
8
8
  };
9
- type ComputedFetchOptions<R extends HoleFetchRequest> = ComputedOptions<HoleFetchOptions<R>>;
10
- export interface UseFetchOptions<DataT, Transform extends _Transform<DataT, any> = _Transform<DataT, DataT>, PickKeys extends KeyOfRes<Transform> = KeyOfRes<Transform>, R extends HoleFetchRequest = string & {}> extends AsyncDataOptions<DataT, Transform, PickKeys>, ComputedFetchOptions<R> {
9
+ type ComputedFetchOptions<R extends HoleFetchRequest, M extends AvailableRouterMethod<R>> = ComputedOptions<HoleFetchOptions<R, M>>;
10
+ export interface UseFetchOptions<DataT, Transform extends _Transform<DataT, any> = _Transform<DataT, DataT>, PickKeys extends KeyOfRes<Transform> = KeyOfRes<Transform>, R extends HoleFetchRequest = string & {}, M extends AvailableRouterMethod<R> = AvailableRouterMethod<R>> extends AsyncDataOptions<DataT, Transform, PickKeys>, ComputedFetchOptions<R, M> {
11
11
  key?: string;
12
+ $fetch?: typeof globalThis.$fetch;
12
13
  }
13
- export declare function useFetch<ResT = void, ErrorT = FetchError, ReqT extends HoleFetchRequest = HoleFetchRequest, _ResT = ResT extends void ? FetchResult<ReqT> : ResT, Transform extends (res: _ResT) => any = (res: _ResT) => _ResT, PickKeys extends KeyOfRes<Transform> = KeyOfRes<Transform>>(request: Ref<ReqT> | ReqT | (() => ReqT), opts?: UseFetchOptions<_ResT, Transform, PickKeys, ReqT>): AsyncData<PickFrom<ReturnType<Transform>, PickKeys>, ErrorT | null>;
14
- export declare function useLazyFetch<ResT = void, ErrorT = FetchError, ReqT extends HoleFetchRequest = HoleFetchRequest, _ResT = ResT extends void ? FetchResult<ReqT> : ResT, Transform extends (res: _ResT) => any = (res: _ResT) => _ResT, PickKeys extends KeyOfRes<Transform> = KeyOfRes<Transform>>(request: Ref<ReqT> | ReqT | (() => ReqT), opts?: Omit<UseFetchOptions<_ResT, Transform, PickKeys>, 'lazy'>): AsyncData<PickFrom<ReturnType<Transform>, PickKeys>, ErrorT | null>;
14
+ export declare function useFetch<ResT = void, ErrorT = FetchError, ReqT extends HoleFetchRequest = HoleFetchRequest, Method extends AvailableRouterMethod<ReqT> = 'get' extends AvailableRouterMethod<ReqT> ? 'get' : AvailableRouterMethod<ReqT>, _ResT = ResT extends void ? FetchResult<ReqT, Method> : ResT, Transform extends (res: _ResT) => any = (res: _ResT) => _ResT, PickKeys extends KeyOfRes<Transform> = KeyOfRes<Transform>>(request: Ref<ReqT> | ReqT | (() => ReqT), opts?: UseFetchOptions<_ResT, Transform, PickKeys, ReqT, Method>): AsyncData<PickFrom<ReturnType<Transform>, PickKeys>, ErrorT | null>;
15
+ export declare function useLazyFetch<ResT = void, ErrorT = FetchError, ReqT extends HoleFetchRequest = HoleFetchRequest, Method extends AvailableRouterMethod<ReqT> = 'get' extends AvailableRouterMethod<ReqT> ? 'get' : AvailableRouterMethod<ReqT>, _ResT = ResT extends void ? FetchResult<ReqT, Method> : ResT, Transform extends (res: _ResT) => any = (res: _ResT) => _ResT, PickKeys extends KeyOfRes<Transform> = KeyOfRes<Transform>>(request: Ref<ReqT> | ReqT | (() => ReqT), opts?: Omit<UseFetchOptions<_ResT, Transform, PickKeys, Method>, 'lazy'>): AsyncData<PickFrom<ReturnType<Transform>, PickKeys>, ErrorT | null>;
15
16
  export {};
@@ -1,5 +1,6 @@
1
1
  import { computed, unref, reactive } from "kdu";
2
2
  import { hash } from "ohash";
3
+ import { useRequestFetch } from "./ssr.mjs";
3
4
  import { useAsyncData } from "./asyncData.mjs";
4
5
  export function useFetch(request, arg1, arg2) {
5
6
  const [opts = {}, autoKey] = typeof arg1 === "string" ? [{}, arg1] : [arg1, arg2];
@@ -49,7 +50,12 @@ export function useFetch(request, arg1, arg2) {
49
50
  const asyncData = useAsyncData(key, () => {
50
51
  controller?.abort?.();
51
52
  controller = typeof AbortController !== "undefined" ? new AbortController() : {};
52
- return $fetch(_request.value, { signal: controller.signal, ..._fetchOptions });
53
+ const isLocalFetch = typeof _request.value === "string" && _request.value.startsWith("/");
54
+ let _$fetch = opts.$fetch || globalThis.$fetch;
55
+ if (process.server && !opts.$fetch && isLocalFetch) {
56
+ _$fetch = useRequestFetch();
57
+ }
58
+ return _$fetch(_request.value, { signal: controller.signal, ..._fetchOptions });
53
59
  }, _asyncDataOptions);
54
60
  return asyncData;
55
61
  }
@@ -0,0 +1,2 @@
1
+ export type { MetaObject } from '#head';
2
+ export { useHead, useSeoMeta, useServerSeoMeta } from '#head';
@@ -0,0 +1 @@
1
+ export { useHead, useSeoMeta, useServerSeoMeta } from "#head";
@@ -9,9 +9,11 @@ export { useFetch, useLazyFetch } from './fetch';
9
9
  export type { FetchResult, UseFetchOptions } from './fetch';
10
10
  export { useCookie } from './cookie';
11
11
  export type { CookieOptions, CookieRef } from './cookie';
12
- export { useRequestHeaders, useRequestEvent, setResponseStatus } from './ssr';
12
+ export { useRequestHeaders, useRequestEvent, useRequestFetch, setResponseStatus } from './ssr';
13
13
  export { onDtwoReady } from './ready';
14
14
  export { abortNavigation, addRouteMiddleware, defineDtwoRouteMiddleware, onBeforeRouteLeave, onBeforeRouteUpdate, setPageLayout, navigateTo, useRoute, useRouter } from './router';
15
15
  export type { AddRouteMiddlewareOptions, RouteMiddleware } from './router';
16
16
  export { preloadComponents, prefetchComponents, preloadRouteComponents } from './preload';
17
17
  export { isPrerendered, loadPayload, preloadPayload } from './payload';
18
+ export type { MetaObject } from './head';
19
+ export { useHead, useSeoMeta, useServerSeoMeta } from './head';
@@ -5,8 +5,9 @@ export { useState } from "./state.mjs";
5
5
  export { clearError, createError, isDtwoError, showError, useError } from "./error.mjs";
6
6
  export { useFetch, useLazyFetch } from "./fetch.mjs";
7
7
  export { useCookie } from "./cookie.mjs";
8
- export { useRequestHeaders, useRequestEvent, setResponseStatus } from "./ssr.mjs";
8
+ export { useRequestHeaders, useRequestEvent, useRequestFetch, setResponseStatus } from "./ssr.mjs";
9
9
  export { onDtwoReady } from "./ready.mjs";
10
10
  export { abortNavigation, addRouteMiddleware, defineDtwoRouteMiddleware, onBeforeRouteLeave, onBeforeRouteUpdate, setPageLayout, navigateTo, useRoute, useRouter } from "./router.mjs";
11
11
  export { preloadComponents, prefetchComponents, preloadRouteComponents } from "./preload.mjs";
12
12
  export { isPrerendered, loadPayload, preloadPayload } from "./payload.mjs";
13
+ export { useHead, useSeoMeta, useServerSeoMeta } from "./head.mjs";
@@ -1,6 +1,6 @@
1
1
  import { joinURL } from "ufo";
2
- import { useDtwoApp } from "../dtwo.mjs";
3
- import { useHead, useRuntimeConfig } from "../index.mjs";
2
+ import { useDtwoApp, useRuntimeConfig } from "../dtwo.mjs";
3
+ import { useHead } from "./head.mjs";
4
4
  export function loadPayload(url, opts = {}) {
5
5
  if (process.server) {
6
6
  return null;
@@ -26,11 +26,11 @@ export async function preloadRouteComponents(to, router = useRouter()) {
26
26
  if (router._routePreloaded.has(to)) {
27
27
  return;
28
28
  }
29
- router._routePreloaded.add(to);
30
29
  const promises = router._preloadPromises = router._preloadPromises || [];
31
30
  if (promises.length > 4) {
32
31
  return Promise.all(promises).then(() => preloadRouteComponents(to, router));
33
32
  }
33
+ router._routePreloaded.add(to);
34
34
  const components = router.resolve(to).matched.map((component) => component.components?.default).filter((component) => typeof component === "function");
35
35
  for (const component of components) {
36
36
  const promise = Promise.resolve(component()).catch(() => {
@@ -3,4 +3,5 @@ import type { DtwoApp } from '../dtwo';
3
3
  export declare function useRequestHeaders<K extends string = string>(include: K[]): Record<Lowercase<K>, string | undefined>;
4
4
  export declare function useRequestHeaders(): Readonly<Record<string, string | undefined>>;
5
5
  export declare function useRequestEvent(dtwoApp?: DtwoApp): H3Event;
6
+ export declare function useRequestFetch(): typeof global.$fetch;
6
7
  export declare function setResponseStatus(code: number, message?: string): void;
@@ -12,6 +12,13 @@ export function useRequestHeaders(include) {
12
12
  export function useRequestEvent(dtwoApp = useDtwoApp()) {
13
13
  return dtwoApp.ssrContext?.event;
14
14
  }
15
+ export function useRequestFetch() {
16
+ if (process.client) {
17
+ return globalThis.$fetch;
18
+ }
19
+ const event = useDtwoApp().ssrContext?.event;
20
+ return event?.$fetch || globalThis.$fetch;
21
+ }
15
22
  export function setResponseStatus(code, message) {
16
23
  const event = process.server && useRequestEvent();
17
24
  if (event) {
@@ -0,0 +1,2 @@
1
+ declare const _default: () => void;
2
+ export default _default;
@@ -0,0 +1,2 @@
1
+ export default () => {
2
+ };
@@ -1,7 +1,7 @@
1
1
  import { createSSRApp, createApp, nextTick } from "kdu";
2
2
  import { $fetch } from "ofetch";
3
3
  import { baseURL } from "#build/paths.mjs";
4
- import { createDtwoApp, applyPlugins, normalizePlugins } from "#app";
4
+ import { createDtwoApp, applyPlugins, normalizePlugins } from "#app/dtwo";
5
5
  import "#build/css";
6
6
  import _plugins from "#build/plugins";
7
7
  import RootComponent from "#build/root-component.mjs";
@@ -4,7 +4,5 @@ export * from './composables';
4
4
  export * from './components';
5
5
  export * from './config';
6
6
  export type { PageMeta } from '../pages/runtime';
7
- export type { MetaObject } from '../head/runtime';
8
- export { useHead } from '#head';
9
7
  export declare const isKdu2 = false;
10
8
  export declare const isKdu3 = true;
@@ -2,6 +2,5 @@ export * from "./dtwo.mjs";
2
2
  export * from "./composables/index.mjs";
3
3
  export * from "./components/index.mjs";
4
4
  export * from "./config.mjs";
5
- export { useHead } from "#head";
6
5
  export const isKdu2 = false;
7
6
  export const isKdu3 = true;
@@ -1,6 +1,7 @@
1
1
  import { ref } from "kdu";
2
2
  import { parseURL } from "ufo";
3
- import { defineDtwoPlugin, useHead } from "#app";
3
+ import { defineDtwoPlugin } from "#app/dtwo";
4
+ import { useHead } from "#app/composables/head";
4
5
  export default defineDtwoPlugin((dtwoApp) => {
5
6
  const externalURLs = ref(/* @__PURE__ */ new Set());
6
7
  function generateRules() {
@@ -1,5 +1,5 @@
1
1
  import { createDebugger } from "hookable";
2
- import { defineDtwoPlugin } from "#app";
2
+ import { defineDtwoPlugin } from "#app/dtwo";
3
3
  export default defineDtwoPlugin((dtwoApp) => {
4
4
  createDebugger(dtwoApp.hooks, { tag: "dtwo-app" });
5
5
  });
@@ -1,5 +1,7 @@
1
1
  import { parseURL } from "ufo";
2
- import { defineDtwoPlugin, loadPayload, isPrerendered, useRouter } from "#app";
2
+ import { defineDtwoPlugin } from "#app/dtwo";
3
+ import { loadPayload, isPrerendered } from "#app/composables/payload";
4
+ import { useRouter } from "#app/composables/router";
3
5
  export default defineDtwoPlugin((dtwoApp) => {
4
6
  if (!isPrerendered()) {
5
7
  return;
@@ -1,4 +1,4 @@
1
- import { defineDtwoPlugin } from "#app";
1
+ import { defineDtwoPlugin } from "#app/dtwo";
2
2
  export default defineDtwoPlugin((dtwoApp) => {
3
3
  dtwoApp.kduApp.mixin({
4
4
  beforeCreate() {
@@ -46,7 +46,7 @@ interface Router {
46
46
  hasRoute: (name: string) => boolean;
47
47
  removeRoute: (name: string) => void;
48
48
  }
49
- declare const _default: import("..").Plugin<{
49
+ declare const _default: import("../dtwo").Plugin<{
50
50
  route: Route;
51
51
  router: Router;
52
52
  }>;
@@ -1,7 +1,11 @@
1
1
  import { reactive, h, isReadonly } from "kdu";
2
2
  import { parseURL, stringifyParsedURL, parseQuery, stringifyQuery, withoutBase, isEqual, joinURL } from "ufo";
3
3
  import { createError } from "h3";
4
- import { defineDtwoPlugin, clearError, navigateTo, showError, useRuntimeConfig, useState, useRequestEvent } from "../index.mjs";
4
+ import { defineDtwoPlugin, useRuntimeConfig } from "../dtwo.mjs";
5
+ import { clearError, showError } from "../composables/error.mjs";
6
+ import { navigateTo } from "../composables/router.mjs";
7
+ import { useState } from "../composables/state.mjs";
8
+ import { useRequestEvent } from "../composables/ssr.mjs";
5
9
  import { callWithDtwo } from "../dtwo.mjs";
6
10
  import { globalMiddleware } from "#build/middleware";
7
11
  function getRouteFromPath(fullPath) {
@@ -2,7 +2,10 @@ import { defineComponent, createStaticKNode, computed, h, watch } from "kdu";
2
2
  import { debounce } from "perfect-debounce";
3
3
  import { hash } from "ohash";
4
4
  import { appendHeader } from "h3";
5
- import { useAsyncData, useHead, useDtwoApp, useRequestEvent } from "#app";
5
+ import { useDtwoApp } from "#app/dtwo";
6
+ import { useRequestEvent } from "#app/composables/ssr";
7
+ import { useAsyncData } from "#app/composables/asyncData";
8
+ import { useHead } from "#app/composables/head";
6
9
  const pKey = "_islandPromises";
7
10
  export const createServerComponent = (name) => {
8
11
  return defineComponent({
@@ -1,5 +1,5 @@
1
1
  import { useSeoMeta as _useSeoMeta } from "@kduse/head";
2
- import { useDtwoApp } from "#app";
2
+ import { useDtwoApp } from "#app/dtwo";
3
3
  export function useHead(input, options) {
4
4
  return useDtwoApp()._useHead(input, options);
5
5
  }
@@ -1,6 +1,6 @@
1
1
  import { createHead, useHead } from "@kduse/head";
2
2
  import { renderSSRHead } from "@kdhead/ssr";
3
- import { defineDtwoPlugin } from "#app";
3
+ import { defineDtwoPlugin } from "#app/dtwo";
4
4
  import { appHead } from "#build/dtwo.config.mjs";
5
5
  export default defineDtwoPlugin((dtwoApp) => {
6
6
  const head = createHead();
package/dist/index.mjs CHANGED
@@ -16,7 +16,6 @@ import { walk } from 'estree-walker';
16
16
  import MagicString from 'magic-string';
17
17
  import { globby } from 'globby';
18
18
  import { hyphenate } from '@kdujs/shared';
19
- import { parse, walk as walk$1, ELEMENT_NODE } from 'ultrahtml';
20
19
  import { defineKdimportPreset, createKdimport, scanDirExports } from 'kdimport';
21
20
  import { createRequire } from 'node:module';
22
21
  import { createTransformer } from 'unctx/transform';
@@ -638,7 +637,7 @@ const componentsPluginTemplate = {
638
637
  getContents({ options }) {
639
638
  const globalComponents = options.getComponents().filter((c) => c.global === true);
640
639
  return `import { defineAsyncComponent } from 'kdu'
641
- import { defineDtwoPlugin } from '#app'
640
+ import { defineDtwoPlugin } from '#app/dtwo'
642
641
 
643
642
  const components = ${genObjectFromRawEntries(globalComponents.map((c) => {
644
643
  const exp = c.export === "default" ? "c.default || c" : `c['${c.export}']`;
@@ -900,44 +899,99 @@ function findComponent(components, name, mode) {
900
899
  return otherModeComponent;
901
900
  }
902
901
 
903
- const PLACEHOLDER_RE = /^(k-slot|#)(fallback|placeholder)/;
902
+ const SSR_RENDER_RE = /ssrRenderComponent/;
903
+ const PLACEHOLDER_EXACT_RE = /^(fallback|placeholder)$/;
904
904
  const TreeShakeTemplatePlugin = createUnplugin((options) => {
905
905
  const regexpMap = /* @__PURE__ */ new WeakMap();
906
906
  return {
907
907
  name: "dtwo:tree-shake-template",
908
- enforce: "pre",
908
+ enforce: "post",
909
909
  transformInclude(id) {
910
910
  const { pathname } = parseURL(decodeURIComponent(pathToFileURL(id).href));
911
911
  return pathname.endsWith(".kdu");
912
912
  },
913
- async transform(code, id) {
914
- const template = code.match(/<template>([\s\S]*)<\/template>/);
915
- if (!template) {
916
- return;
917
- }
913
+ transform(code, id) {
918
914
  const components = options.getComponents();
919
915
  if (!regexpMap.has(components)) {
920
- const clientOnlyComponents2 = components.filter((c) => c.mode === "client" && !components.some((other) => other.mode !== "client" && other.pascalName === c.pascalName)).flatMap((c) => [c.pascalName, c.kebabName]).concat(["ClientOnly", "client-only"]);
921
- const tags = clientOnlyComponents2.map((component) => `<(${component})[^>]*>[\\s\\S]*?<\\/(${component})>`);
922
- regexpMap.set(components, [new RegExp(`(${tags.join("|")})`, "g"), clientOnlyComponents2]);
916
+ const clientOnlyComponents = components.filter((c) => c.mode === "client" && !components.some((other) => other.mode !== "client" && other.pascalName === c.pascalName && other.filePath !== resolve(distDir, "app/components/server-placeholder"))).flatMap((c) => [c.pascalName, c.kebabName.replaceAll("-", "_")]).concat(["ClientOnly", "client_only"]);
917
+ regexpMap.set(components, [new RegExp(`(${clientOnlyComponents.join("|")})`), new RegExp(`^(${clientOnlyComponents.map((c) => `(?:(?:_unref\\()?(?:_component_)?(?:Lazy|lazy_)?${c}\\)?)`).join("|")})$`), clientOnlyComponents]);
923
918
  }
924
- const [COMPONENTS_RE, clientOnlyComponents] = regexpMap.get(components);
919
+ const s = new MagicString(code);
920
+ const importDeclarations = [];
921
+ const [COMPONENTS_RE, COMPONENTS_IDENTIFIERS_RE] = regexpMap.get(components);
925
922
  if (!COMPONENTS_RE.test(code)) {
926
923
  return;
927
924
  }
928
- const s = new MagicString(code);
929
- const ast = parse(template[0]);
930
- await walk$1(ast, (node) => {
931
- if (node.type !== ELEMENT_NODE || !clientOnlyComponents.includes(node.name) || !node.children?.length) {
932
- return;
933
- }
934
- const fallback = node.children.find(
935
- (n) => n.name === "template" && Object.entries(n.attributes)?.flat().some((attr) => PLACEHOLDER_RE.test(attr))
936
- );
937
- try {
938
- const text = fallback ? code.slice(template.index + fallback.loc[0].start, template.index + fallback.loc[fallback.loc.length - 1].end) : "";
939
- s.overwrite(template.index + node.loc[0].end, template.index + node.loc[node.loc.length - 1].start, text);
940
- } catch (err) {
925
+ walk(this.parse(code, { sourceType: "module", ecmaVersion: "latest" }), {
926
+ enter: (_node) => {
927
+ const node = _node;
928
+ if (node.type === "ImportDeclaration") {
929
+ importDeclarations.push(node);
930
+ } else if (node.type === "CallExpression" && node.callee.type === "Identifier" && SSR_RENDER_RE.test(node.callee.name)) {
931
+ const [componentCall, _, children] = node.arguments;
932
+ if (componentCall.type === "Identifier" || componentCall.type === "MemberExpression" || componentCall.type === "CallExpression") {
933
+ const componentName = getComponentName(node);
934
+ const isClientComponent = COMPONENTS_IDENTIFIERS_RE.test(componentName);
935
+ const isClientOnlyComponent = /^(?:_unref\()?(?:_component_)?(?:Lazy|lazy_)?(?:client_only|ClientOnly\)?)$/.test(componentName);
936
+ if (isClientComponent && children?.type === "ObjectExpression") {
937
+ const slotsToRemove = isClientOnlyComponent ? children.properties.filter((prop) => prop.type === "Property" && prop.key.type === "Identifier" && !PLACEHOLDER_EXACT_RE.test(prop.key.name)) : children.properties;
938
+ for (const slot of slotsToRemove) {
939
+ const componentsSet = /* @__PURE__ */ new Set();
940
+ s.remove(slot.start, slot.end + 1);
941
+ const removedCode = `({${code.slice(slot.start, slot.end + 1)}})`;
942
+ const currentCode = s.toString();
943
+ walk(this.parse(removedCode, { sourceType: "module", ecmaVersion: "latest" }), {
944
+ enter: (_node2) => {
945
+ const node2 = _node2;
946
+ if (node2.type === "CallExpression" && node2.callee.type === "Identifier" && SSR_RENDER_RE.test(node2.callee.name)) {
947
+ const componentNode = node2.arguments[0];
948
+ if (componentNode.type === "CallExpression") {
949
+ const identifier = componentNode.arguments[0];
950
+ if (!isRenderedInCode(currentCode, removedCode.slice(componentNode.start, componentNode.end))) {
951
+ componentsSet.add(identifier.name);
952
+ }
953
+ } else if (componentNode.type === "Identifier" && !isRenderedInCode(currentCode, componentNode.name)) {
954
+ componentsSet.add(componentNode.name);
955
+ } else if (componentNode.type === "MemberExpression") {
956
+ const { start, end } = componentNode;
957
+ if (!isRenderedInCode(currentCode, removedCode.slice(start, end))) {
958
+ componentsSet.add(componentNode.property.value);
959
+ walk(this.parse(code, { sourceType: "module", ecmaVersion: "latest" }), {
960
+ enter: (node3) => {
961
+ removeFromSetupReturnStatement(s, node3, componentNode.property.value);
962
+ }
963
+ });
964
+ }
965
+ }
966
+ }
967
+ }
968
+ });
969
+ const componentsToRemove = [...componentsSet];
970
+ for (const componentName2 of componentsToRemove) {
971
+ let removed = false;
972
+ const VAR_RE = new RegExp(`(?:const|let|var) ${componentName2} = ([^;\\n]*);?`);
973
+ s.replace(VAR_RE, () => {
974
+ removed = true;
975
+ return "";
976
+ });
977
+ if (!removed) {
978
+ const declaration = findImportDeclaration(importDeclarations, componentName2);
979
+ if (declaration) {
980
+ if (declaration.specifiers.length > 1) {
981
+ const componentSpecifier = declaration.specifiers.find((s2) => s2.local.name === componentName2);
982
+ if (componentSpecifier) {
983
+ s.remove(componentSpecifier.start, componentSpecifier.end + 1);
984
+ }
985
+ } else {
986
+ s.remove(declaration.start, declaration.end);
987
+ }
988
+ }
989
+ }
990
+ }
991
+ }
992
+ }
993
+ }
994
+ }
941
995
  }
942
996
  });
943
997
  if (s.hasChanged()) {
@@ -949,6 +1003,46 @@ const TreeShakeTemplatePlugin = createUnplugin((options) => {
949
1003
  }
950
1004
  };
951
1005
  });
1006
+ function findImportDeclaration(declarations, importName) {
1007
+ const declaration = declarations.find((d) => {
1008
+ const specifier = d.specifiers.find((s) => s.local.name === importName);
1009
+ if (specifier) {
1010
+ return true;
1011
+ }
1012
+ return false;
1013
+ });
1014
+ return declaration;
1015
+ }
1016
+ function isRenderedInCode(code, name) {
1017
+ return new RegExp(`ssrRenderComponent\\(${escapeRE(name)}`).test(code);
1018
+ }
1019
+ function getComponentName(ssrRenderNode) {
1020
+ const componentCall = ssrRenderNode.arguments[0];
1021
+ if (componentCall.type === "Identifier") {
1022
+ return componentCall.name;
1023
+ } else if (componentCall.type === "MemberExpression") {
1024
+ return componentCall.property.value;
1025
+ }
1026
+ return componentCall.arguments[0].name;
1027
+ }
1028
+ function removeFromSetupReturnStatement(s, node, name) {
1029
+ if (node.type === "Property" && node.key.type === "Identifier" && node.key.name === "setup" && node.value.type === "FunctionExpression") {
1030
+ const returnStatement = node.value.body.body.find((n) => n.type === "ReturnStatement");
1031
+ if (returnStatement?.argument?.type === "Identifier") {
1032
+ const returnIdentifier = returnStatement.argument.name;
1033
+ const returnedDeclaration = node.value.body.body.find((n) => n.type === "VariableDeclaration" && n.declarations[0].id.name === returnIdentifier);
1034
+ const componentProperty = returnedDeclaration?.declarations[0].init?.properties.find((p) => p.key.name === name);
1035
+ if (componentProperty) {
1036
+ s.remove(componentProperty.start, componentProperty.end + 1);
1037
+ }
1038
+ } else if (returnStatement?.argument?.type === "ObjectExpression") {
1039
+ const componentProperty = returnStatement.argument?.properties.find((p) => p.key.name === name);
1040
+ if (componentProperty) {
1041
+ s.remove(componentProperty.start, componentProperty.end + 1);
1042
+ }
1043
+ }
1044
+ }
1045
+ }
952
1046
 
953
1047
  const isPureObjectOrString = (val) => !Array.isArray(val) && typeof val === "object" || typeof val === "string";
954
1048
  const isDirectory = (p) => {
@@ -1104,35 +1198,35 @@ const componentsModule = defineDtwoModule({
1104
1198
  dtwo.hook("wite:extendConfig", (config, { isClient, isServer }) => {
1105
1199
  const mode = isClient ? "client" : "server";
1106
1200
  config.plugins = config.plugins || [];
1107
- config.plugins.push(loaderPlugin.wite({
1108
- sourcemap: dtwo.options.sourcemap[mode],
1109
- getComponents,
1110
- mode,
1111
- experimentalComponentIslands: dtwo.options.experimental.componentIslands
1112
- }));
1113
1201
  if (dtwo.options.experimental.treeshakeClientOnly && isServer) {
1114
1202
  config.plugins.push(TreeShakeTemplatePlugin.wite({
1115
1203
  sourcemap: dtwo.options.sourcemap[mode],
1116
1204
  getComponents
1117
1205
  }));
1118
1206
  }
1207
+ config.plugins.push(loaderPlugin.wite({
1208
+ sourcemap: dtwo.options.sourcemap[mode],
1209
+ getComponents,
1210
+ mode,
1211
+ experimentalComponentIslands: dtwo.options.experimental.componentIslands
1212
+ }));
1119
1213
  });
1120
1214
  dtwo.hook("webpack:config", (configs) => {
1121
1215
  configs.forEach((config) => {
1122
1216
  const mode = config.name === "client" ? "client" : "server";
1123
1217
  config.plugins = config.plugins || [];
1124
- config.plugins.push(loaderPlugin.webpack({
1125
- sourcemap: dtwo.options.sourcemap[mode],
1126
- getComponents,
1127
- mode,
1128
- experimentalComponentIslands: dtwo.options.experimental.componentIslands
1129
- }));
1130
1218
  if (dtwo.options.experimental.treeshakeClientOnly && mode === "server") {
1131
1219
  config.plugins.push(TreeShakeTemplatePlugin.webpack({
1132
1220
  sourcemap: dtwo.options.sourcemap[mode],
1133
1221
  getComponents
1134
1222
  }));
1135
1223
  }
1224
+ config.plugins.push(loaderPlugin.webpack({
1225
+ sourcemap: dtwo.options.sourcemap[mode],
1226
+ getComponents,
1227
+ mode,
1228
+ experimentalComponentIslands: dtwo.options.experimental.componentIslands
1229
+ }));
1136
1230
  });
1137
1231
  });
1138
1232
  }
@@ -1176,15 +1270,6 @@ const TransformPlugin = createUnplugin(({ ctx, options, sourcemap }) => {
1176
1270
  });
1177
1271
 
1178
1272
  const commonPresets = [
1179
- // #head
1180
- defineKdimportPreset({
1181
- from: "#head",
1182
- imports: [
1183
- "useHead",
1184
- "useSeoMeta",
1185
- "useServerSeoMeta"
1186
- ]
1187
- }),
1188
1273
  // kdu-demi (mocked)
1189
1274
  defineKdimportPreset({
1190
1275
  from: "kdu-demi",
@@ -1197,6 +1282,9 @@ const commonPresets = [
1197
1282
  const appPreset = defineKdimportPreset({
1198
1283
  from: "#app",
1199
1284
  imports: [
1285
+ "useHead",
1286
+ "useSeoMeta",
1287
+ "useServerSeoMeta",
1200
1288
  "useAsyncData",
1201
1289
  "useLazyAsyncData",
1202
1290
  "useDtwoData",
@@ -1212,6 +1300,7 @@ const appPreset = defineKdimportPreset({
1212
1300
  "useCookie",
1213
1301
  "useRequestHeaders",
1214
1302
  "useRequestEvent",
1303
+ "useRequestFetch",
1215
1304
  "setResponseStatus",
1216
1305
  "setPageLayout",
1217
1306
  "onDtwoReady",
@@ -1312,11 +1401,25 @@ const kduPreset = defineKdimportPreset({
1312
1401
  "useTransitionState"
1313
1402
  ]
1314
1403
  });
1404
+ const kduTypesPreset = defineKdimportPreset({
1405
+ from: "kdu",
1406
+ type: true,
1407
+ imports: [
1408
+ "Component",
1409
+ "ComponentPublicInstance",
1410
+ "ComputedRef",
1411
+ "InjectionKey",
1412
+ "PropType",
1413
+ "Ref",
1414
+ "KNode"
1415
+ ]
1416
+ });
1315
1417
  const defaultPresets = [
1316
1418
  ...commonPresets,
1317
1419
  appPreset,
1318
1420
  routerPreset,
1319
- kduPreset
1421
+ kduPreset,
1422
+ kduTypesPreset
1320
1423
  ];
1321
1424
 
1322
1425
  const importsModule = defineDtwoModule({
@@ -1430,7 +1533,7 @@ function addDeclarationTemplates(ctx, options) {
1430
1533
  });
1431
1534
  }
1432
1535
 
1433
- const version = "3.1.2";
1536
+ const version = "3.2.0";
1434
1537
 
1435
1538
  const _require = createRequire(import.meta.url);
1436
1539
  const kduAppPatterns = (dtwo) => [
@@ -1600,6 +1703,11 @@ const addModuleTranspiles = (opts = {}) => {
1600
1703
 
1601
1704
  async function initHole(dtwo) {
1602
1705
  const _holeConfig = dtwo.options.hole || {};
1706
+ const excludePaths = dtwo.options._layers.flatMap((l) => [
1707
+ l.cwd.match(/(?<=\/)node_modules\/(.+)$/)?.[1],
1708
+ l.cwd.match(/\.pnpm\/.+\/node_modules\/(.+)$/)?.[1]
1709
+ ]).filter((dir) => Boolean(dir)).map((dir) => escapeRE(dir));
1710
+ const excludePattern = excludePaths.length ? [new RegExp(`node_modules\\/(?!${excludePaths.join("|")})`)] : [/node_modules/];
1603
1711
  const holeConfig = defu(_holeConfig, {
1604
1712
  debug: dtwo.options.debug,
1605
1713
  rootDir: dtwo.options.rootDir,
@@ -1619,14 +1727,11 @@ async function initHole(dtwo) {
1619
1727
  name: "publicAssetsURL",
1620
1728
  from: resolve(distDir, "core/runtime/hole/paths")
1621
1729
  }
1622
- ]
1730
+ ],
1731
+ exclude: [...excludePattern, /[\\/]\.git[\\/]/]
1623
1732
  },
1624
1733
  esbuild: {
1625
- options: {
1626
- exclude: [
1627
- new RegExp(`node_modules\\/(?!${dtwo.options._layers.map((l) => l.cwd.match(/(?<=\/)node_modules\/(.+)$/)?.[1]).filter(Boolean).map((dir) => escapeRE(dir)).join("|")})`)
1628
- ]
1629
- }
1734
+ options: { exclude: excludePattern }
1630
1735
  },
1631
1736
  analyze: dtwo.options.build.analyze && {
1632
1737
  template: "treemap",
@@ -1657,7 +1762,11 @@ async function initHole(dtwo) {
1657
1762
  generateTsConfig: false
1658
1763
  },
1659
1764
  publicAssets: [
1660
- { dir: resolve(dtwo.options.buildDir, "dist/client") },
1765
+ dtwo.options.dev ? { dir: resolve(dtwo.options.buildDir, "dist/client") } : {
1766
+ dir: join(dtwo.options.buildDir, "dist/client", dtwo.options.app.buildAssetsDir),
1767
+ maxAge: 30 * 24 * 60 * 60,
1768
+ baseURL: dtwo.options.app.buildAssetsDir
1769
+ },
1661
1770
  ...dtwo.options._layers.map((layer) => join(layer.config.srcDir, layer.config.dir?.public || "public")).filter((dir) => existsSync(dir)).map((dir) => ({ dir }))
1662
1771
  ],
1663
1772
  prerender: {
@@ -1717,9 +1826,15 @@ async function initHole(dtwo) {
1717
1826
  holeConfig.virtual["#head-static"] = `export default ${JSON.stringify(headChunk)}`;
1718
1827
  if (!dtwo.options.ssr) {
1719
1828
  holeConfig.virtual["#build/dist/server/server.mjs"] = "export default () => {}";
1829
+ if (process.platform === "win32") {
1830
+ holeConfig.virtual["#build/dist/server/server.mjs".replace(/\//g, "\\")] = "export default () => {}";
1831
+ }
1720
1832
  }
1721
1833
  if (!dtwo.options.experimental.inlineSSRStyles) {
1722
1834
  holeConfig.virtual["#build/dist/server/styles.mjs"] = "export default {}";
1835
+ if (process.platform === "win32") {
1836
+ holeConfig.virtual["#build/dist/server/styles.mjs".replace(/\//g, "\\")] = "export default {}";
1837
+ }
1723
1838
  }
1724
1839
  holeConfig.rollupConfig.plugins = await holeConfig.rollupConfig.plugins || [];
1725
1840
  holeConfig.rollupConfig.plugins = Array.isArray(holeConfig.rollupConfig.plugins) ? holeConfig.rollupConfig.plugins : [holeConfig.rollupConfig.plugins];
@@ -2,7 +2,7 @@ import { computed, defineComponent, h, provide, reactive, onMounted, nextTick, S
2
2
  import { RouterView } from "kdu-router";
3
3
  import { defu } from "defu";
4
4
  import { generateRouteKey, wrapInKeepAlive } from "./utils.mjs";
5
- import { useDtwoApp } from "#app";
5
+ import { useDtwoApp } from "#app/dtwo";
6
6
  import { _wrapIf } from "#app/components/utils";
7
7
  import { appPageTransition as defaultPageTransition, appKeepalive as defaultKeepaliveConfig } from "#build/dtwo.config.mjs";
8
8
  export default defineComponent({
@@ -1,5 +1,6 @@
1
1
  import { hasProtocol } from "ufo";
2
- import { defineDtwoPlugin, useDtwoApp, useRouter } from "#app";
2
+ import { defineDtwoPlugin, useDtwoApp } from "#app/dtwo";
3
+ import { useRouter } from "#app/composables/router";
3
4
  import layouts from "#build/layouts";
4
5
  import { namedMiddleware } from "#build/middleware";
5
6
  export default defineDtwoPlugin(() => {
@@ -7,7 +7,11 @@ import {
7
7
  } from "kdu-router";
8
8
  import { createError } from "h3";
9
9
  import { withoutBase, isEqual } from "ufo";
10
- import { callWithDtwo, defineDtwoPlugin, useRuntimeConfig, showError, clearError, navigateTo, useError, useState, useRequestEvent } from "#app";
10
+ import { callWithDtwo, defineDtwoPlugin, useRuntimeConfig } from "#app/dtwo";
11
+ import { showError, clearError, useError } from "#app/composables/error";
12
+ import { useRequestEvent } from "#app/composables/ssr";
13
+ import { useState } from "#app/composables/state";
14
+ import { navigateTo } from "#app/composables/router";
11
15
  import _routes from "#build/routes";
12
16
  import routerOptions from "#build/router.options";
13
17
  import { globalMiddleware, namedMiddleware } from "#build/middleware";
@@ -1,5 +1,5 @@
1
1
  import { nextTick } from "kdu";
2
- import { useDtwoApp } from "#app";
2
+ import { useDtwoApp } from "#app/dtwo";
3
3
  import { appPageTransition as defaultPageTransition } from "#build/dtwo.config.mjs";
4
4
  export default {
5
5
  scrollBehavior(to, from, savedPosition) {
@@ -1,4 +1,4 @@
1
- import { defineDtwoRouteMiddleware } from "#app";
1
+ import { defineDtwoRouteMiddleware } from "#app/composables/router";
2
2
  export default defineDtwoRouteMiddleware(async (to) => {
3
3
  if (!to.meta?.validate) {
4
4
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dtwo",
3
- "version": "3.1.2",
3
+ "version": "3.2.0",
4
4
  "repository": "d2js/dtwo",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -13,9 +13,9 @@
13
13
  "exports": {
14
14
  ".": "./dist/index.mjs",
15
15
  "./config": {
16
+ "types": "./config.d.ts",
16
17
  "import": "./config.mjs",
17
- "require": "./config.cjs",
18
- "types": "./config.d.ts"
18
+ "require": "./config.cjs"
19
19
  },
20
20
  "./app": "./dist/app/index.mjs",
21
21
  "./package.json": "./package.json"
@@ -34,34 +34,34 @@
34
34
  ],
35
35
  "dependencies": {
36
36
  "@d2js/devalue": "2.0.2",
37
- "@dtwo/kit": "3.1.2",
38
- "@dtwo/schema": "3.1.2",
37
+ "@dtwo/kit": "3.2.0",
38
+ "@dtwo/schema": "3.2.0",
39
39
  "@dtwo/telemetry": "2.1.8",
40
40
  "@dtwo/ui-templates": "1.1.1",
41
41
  "@dtwo/unplugin": "1.0.0",
42
- "@dtwo/wite-builder": "3.1.2",
43
- "@kdhead/ssr": "1.0.20",
42
+ "@dtwo/wite-builder": "3.2.0",
43
+ "@kdhead/ssr": "1.0.21",
44
44
  "@kdujs/reactivity": "3.2.48",
45
45
  "@kdujs/shared": "3.2.48",
46
- "@kduse/head": "1.0.24",
46
+ "@kduse/head": "1.0.25",
47
47
  "chokidar": "3.5.3",
48
48
  "cookie-es": "0.5.0",
49
49
  "defu": "6.1.2",
50
50
  "destr": "1.2.2",
51
- "dtwc": "3.1.2",
51
+ "dtwc": "3.2.0",
52
52
  "escape-string-regexp": "5.0.0",
53
53
  "estree-walker": "3.0.3",
54
54
  "fs-extra": "11.1.0",
55
55
  "globby": "13.1.3",
56
- "h3": "1.1.0",
56
+ "h3": "1.4.0",
57
57
  "hash-sum": "2.0.0",
58
- "holepack": "2.1.1",
58
+ "holepack": "2.2.1",
59
59
  "hookable": "5.4.2",
60
- "jiti": "1.16.2",
61
- "kdhead": "1.0.20",
62
- "kdimport": "2.1.0",
60
+ "jiti": "1.17.0",
61
+ "kdhead": "1.0.21",
62
+ "kdimport": "2.2.4",
63
63
  "kdu": "3.2.48",
64
- "kdu-bundle-renderer": "1.0.0",
64
+ "kdu-bundle-renderer": "1.0.1",
65
65
  "kdu-devtools-stub": "0.1.0",
66
66
  "kdu-router": "4.1.6",
67
67
  "knitwork": "1.0.0",
@@ -72,11 +72,10 @@
72
72
  "pathe": "1.1.0",
73
73
  "perfect-debounce": "0.1.3",
74
74
  "scule": "1.0.0",
75
- "strip-literal": "1.0.0",
75
+ "strip-literal": "1.0.1",
76
76
  "ufo": "1.0.1",
77
- "ultrahtml": "1.2.0",
78
77
  "unctx": "2.1.1",
79
- "unenv": "1.0.3",
78
+ "unenv": "1.1.1",
80
79
  "untyped": "1.2.2"
81
80
  },
82
81
  "devDependencies": {