@emberkit/core 0.4.2 → 0.6.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.
@@ -1 +1 @@
1
- {"version":3,"file":"hydration.d.ts","sourceRoot":"","sources":["../../../src/hydration/helpers/hydration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAItD,MAAM,WAAW,gBAAgB;IAC/B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACnD,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,kBAAkB,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAC/D;AAED,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,OAAO,GAAG,MAAM,EAC3B,OAAO,EAAE,UAAU,GAAG,IAAI,EAC1B,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAiBf;AA4CD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAcjF;AAgCD,wBAAgB,mBAAmB,CAAC,CAAC,EACnC,MAAM,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACxB,OAAO,GAAE;IACP,QAAQ,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAC9B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAC7B,GACL,UAAU,CA0BZ;AAwCD,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C"}
1
+ {"version":3,"file":"hydration.d.ts","sourceRoot":"","sources":["../../../src/hydration/helpers/hydration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAMtD,MAAM,WAAW,gBAAgB;IAC/B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,kBAAkB,KAAK,IAAI,CAAC;IACnD,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,kBAAkB,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAC/D;AAED,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,OAAO,GAAG,MAAM,EAC3B,OAAO,EAAE,UAAU,GAAG,IAAI,EAC1B,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAiBf;AA4CD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAcjF;AAgCD,wBAAgB,mBAAmB,CAAC,CAAC,EACnC,MAAM,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACxB,OAAO,GAAE;IACP,QAAQ,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAC9B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAC7B,GACL,UAAU,CA4BZ;AAwCD,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C"}
@@ -1,6 +1,8 @@
1
1
  import { createElement } from '../../runtime/index.js';
2
2
  import { analyzeTree, getHydrationCandidates } from './analyzer.js';
3
+ import { observeOnce } from '../../viewport/observe-once.js';
3
4
  const hydrationCache = new Map();
5
+ let lazyHydrationIdCounter = 0;
4
6
  export async function hydrateSelective(container, element, options = {}) {
5
7
  const root = typeof container === 'string' ? document.querySelector(container) : container;
6
8
  if (!root || !element)
@@ -87,13 +89,15 @@ function mapHandlerToEvent(handler) {
87
89
  }
88
90
  export function createLazyHydration(loader, options = {}) {
89
91
  const { fallback = createElement('div', { 'data-loading': '' }, 'Loading...'), timeout, onLoaded, onError, } = options;
92
+ const lazyId = `ek-hydrate-${++lazyHydrationIdCounter}`;
90
93
  const container = createElement('div', {
91
94
  'data-lazy': '',
95
+ 'data-lazy-id': lazyId,
92
96
  'data-loader': loader.toString(),
93
97
  }, fallback);
94
98
  if (typeof IntersectionObserver !== 'undefined') {
95
99
  requestAnimationFrame(() => {
96
- observeAndHydrate(container, loader, timeout, onLoaded, onError);
100
+ observeAndHydrate(lazyId, loader, timeout, onLoaded, onError);
97
101
  });
98
102
  }
99
103
  else {
@@ -101,17 +105,15 @@ export function createLazyHydration(loader, options = {}) {
101
105
  }
102
106
  return container;
103
107
  }
104
- function observeAndHydrate(container, loader, timeout, onLoaded, onError) {
105
- const observer = new IntersectionObserver((entries) => {
106
- if (entries[0]?.isIntersecting) {
107
- observer.disconnect();
108
- loadImmediately(loader, onLoaded, onError);
109
- }
110
- }, { rootMargin: '100px' });
111
- const root = document.querySelector(`[data-lazy]`);
112
- if (root) {
113
- observer.observe(root);
108
+ function observeAndHydrate(lazyId, loader, timeout, onLoaded, onError) {
109
+ const root = document.querySelector(`[data-lazy-id="${lazyId}"]`);
110
+ if (!root) {
111
+ return;
114
112
  }
113
+ observeOnce(root, () => {
114
+ void timeout;
115
+ void loadImmediately(loader, onLoaded, onError);
116
+ }, { rootMargin: '100px' });
115
117
  }
116
118
  async function loadImmediately(loader, onLoaded, onError) {
117
119
  try {
package/dist/index.d.ts CHANGED
@@ -11,13 +11,15 @@ export type { Signal, WritableSignal, ReadonlySignal } from './signals/index.js'
11
11
  export { createMarkdownParser, parseMarkdown, renderMarkdown, extractFrontmatter, } from './markdown/index.js';
12
12
  export { compileMDX, compileSync, useMDX } from './mdx/index.js';
13
13
  export { DataCache, createCache, getCached, setCache, prefetch } from './cache/index.js';
14
+ export { LazyInView, hydrateLazyInView, clearLazyRegistry } from './viewport/index.js';
14
15
  export { renderToHTMLString } from './ssr/helpers/render-html.js';
15
16
  export { drainHeadContent } from './meta/head-registry.js';
16
17
  export { Head } from './meta/index.js';
17
18
  export type { HeadProps } from './meta/index.js';
18
- export { generateMeta, generateBreadcrumbs, generateArticleSchema, generateProductSchema, } from './meta/index.js';
19
- export type { MetaData, OpenGraphData, TwitterCardData } from './meta/index.js';
19
+ export { generateMeta, buildRouteHeadFromMetadata, generateBreadcrumbs, generateArticleSchema, generateProductSchema, } from './meta/index.js';
20
+ export type { MetaData, OpenGraphData, TwitterCardData, SiteHeadOptions } from './meta/index.js';
20
21
  export type { FC, RouteComponent, RouteChildren, RouteParams } from './runtime/types.js';
22
+ export type { LazyInViewProps } from './viewport/index.js';
21
23
  export type { Logger, LoggerOptions, LogLevel, RequestLog, ResponseLog } from './logger/types.js';
22
24
  export declare function defineConfig(config: Record<string, unknown>): Record<string, unknown>;
23
25
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,OAAO,QAAsB,CAAC;AAE3C,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EACL,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,KAAK,EACL,OAAO,EACP,MAAM,EACN,QAAQ,EACR,MAAM,GACP,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,KAAK,YAAY,EAAE,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC7F,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACnF,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC1E,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACjF,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,cAAc,EACd,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAEjE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEzF,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEhF,YAAY,EAAE,EAAE,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEzF,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAElG,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAErF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,OAAO,QAAsB,CAAC;AAE3C,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EACL,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,KAAK,EACL,OAAO,EACP,MAAM,EACN,QAAQ,EACR,MAAM,GACP,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,KAAK,YAAY,EAAE,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC7F,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACnF,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC1E,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACjF,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,cAAc,EACd,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAEjE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACzF,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAEvF,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EACL,YAAY,EACZ,0BAA0B,EAC1B,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEjG,YAAY,EAAE,EAAE,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACzF,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAElG,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAErF"}
package/dist/index.js CHANGED
@@ -10,10 +10,11 @@ export { createErrorBoundary, createLoadingBoundary } from './boundaries/index.j
10
10
  export { createMarkdownParser, parseMarkdown, renderMarkdown, extractFrontmatter, } from './markdown/index.js';
11
11
  export { compileMDX, compileSync, useMDX } from './mdx/index.js';
12
12
  export { DataCache, createCache, getCached, setCache, prefetch } from './cache/index.js';
13
+ export { LazyInView, hydrateLazyInView, clearLazyRegistry } from './viewport/index.js';
13
14
  export { renderToHTMLString } from './ssr/helpers/render-html.js';
14
15
  export { drainHeadContent } from './meta/head-registry.js';
15
16
  export { Head } from './meta/index.js';
16
- export { generateMeta, generateBreadcrumbs, generateArticleSchema, generateProductSchema, } from './meta/index.js';
17
+ export { generateMeta, buildRouteHeadFromMetadata, generateBreadcrumbs, generateArticleSchema, generateProductSchema, } from './meta/index.js';
17
18
  export function defineConfig(config) {
18
19
  return config;
19
20
  }
@@ -88,4 +88,13 @@ export interface MetaScript {
88
88
  export declare function generateScripts(scripts: MetaScript[]): string;
89
89
  export declare const DEFAULT_META: MetaData;
90
90
  export declare function mergeMeta(base: MetaData, override: Partial<MetaData>): MetaData;
91
+ export interface SiteHeadOptions {
92
+ siteUrl?: string;
93
+ siteName?: string;
94
+ titleSuffix?: string;
95
+ defaultDescription?: string;
96
+ defaultOgImage?: string;
97
+ twitterSite?: string;
98
+ }
99
+ export declare function buildRouteHeadFromMetadata(metadata: MetaData, pathname: string, options?: SiteHeadOptions): string;
91
100
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/meta/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/meta/index.ts"],"names":[],"mappings":"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"}
@@ -208,3 +208,67 @@ export function mergeMeta(base, override) {
208
208
  },
209
209
  };
210
210
  }
211
+ function normalizeSiteUrl(siteUrl) {
212
+ return siteUrl.replace(/\/$/, '');
213
+ }
214
+ function resolvePageUrl(pathname, siteUrl) {
215
+ const path = pathname.startsWith('/') ? pathname : `/${pathname}`;
216
+ if (!siteUrl) {
217
+ return path;
218
+ }
219
+ return `${normalizeSiteUrl(siteUrl)}${path}`;
220
+ }
221
+ function formatRouteTitle(title, titleSuffix) {
222
+ if (!title) {
223
+ return undefined;
224
+ }
225
+ if (!titleSuffix || title.includes(titleSuffix)) {
226
+ return title;
227
+ }
228
+ return `${title} | ${titleSuffix}`;
229
+ }
230
+ export function buildRouteHeadFromMetadata(metadata, pathname, options = {}) {
231
+ const pageUrl = resolvePageUrl(pathname, options.siteUrl);
232
+ const title = formatRouteTitle(metadata.title, options.titleSuffix);
233
+ const description = metadata.description ?? options.defaultDescription;
234
+ const ogImageUrl = metadata.openGraph?.images?.[0]?.url ?? metadata.twitter?.image ?? options.defaultOgImage;
235
+ const openGraphImages = metadata.openGraph?.images ??
236
+ (ogImageUrl
237
+ ? [
238
+ {
239
+ url: ogImageUrl,
240
+ width: 1200,
241
+ height: 630,
242
+ alt: metadata.openGraph?.images?.[0]?.alt ?? title ?? options.siteName,
243
+ },
244
+ ]
245
+ : undefined);
246
+ const merged = {
247
+ ...metadata,
248
+ title,
249
+ description,
250
+ canonical: metadata.canonical ?? pageUrl,
251
+ openGraph: {
252
+ type: 'website',
253
+ locale: 'en_US',
254
+ siteName: options.siteName,
255
+ url: pageUrl,
256
+ title: metadata.openGraph?.title ?? title,
257
+ description: metadata.openGraph?.description ?? description,
258
+ images: openGraphImages,
259
+ ...metadata.openGraph,
260
+ },
261
+ twitter: metadata.twitter ??
262
+ (ogImageUrl
263
+ ? {
264
+ card: 'summary_large_image',
265
+ site: options.twitterSite,
266
+ title: metadata.twitter?.title ?? title,
267
+ description: metadata.twitter?.description ?? description,
268
+ image: ogImageUrl,
269
+ imageAlt: metadata.twitter?.imageAlt ?? title,
270
+ }
271
+ : undefined),
272
+ };
273
+ return generateMeta(merged, pageUrl);
274
+ }
@@ -1,5 +1,8 @@
1
1
  import type { JSXElementProps, JSXNode, DOMElement, JSXElement } from './types.js';
2
2
  export declare function createElement(type: string | ((props: JSXElementProps) => JSXNode), props?: Record<string, unknown> | null, ...children: unknown[]): DOMElement;
3
+ export declare function attachEventHandlers(container: Element): void;
4
+ export declare function hydrateSignalBindings(container: Element): void;
5
+ export declare function hydrateSubtree(container: Element): void;
3
6
  export declare function render(element: JSXElement | string | null | ((props: Record<string, unknown>) => JSXNode), container: Element | string, options?: {
4
7
  hydrate?: boolean;
5
8
  routes?: Array<{
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAKnF,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,eAAe,KAAK,OAAO,CAAC,EACpD,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,EACtC,GAAG,QAAQ,EAAE,OAAO,EAAE,GACrB,UAAU,CAYZ;AA6ID,wBAAgB,MAAM,CACpB,OAAO,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,EACnF,SAAS,EAAE,OAAO,GAAG,MAAM,EAC3B,OAAO,CAAC,EAAE;IACR,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,KAAK,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,OAAO,CAAC;YAAE,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAA;SAAE,CAAC,CAAC;KACpF,CAAC,CAAC;CACJ,GACA,IAAI,CAmFN;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,EAAE,SAAS,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAE9F;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI,CAE9C;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,IAAI,UAAU,CAEjE;AAED,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAMnF,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,eAAe,KAAK,OAAO,CAAC,EACpD,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,EACtC,GAAG,QAAQ,EAAE,OAAO,EAAE,GACrB,UAAU,CAYZ;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAY5D;AAqED,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAwD9D;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAGvD;AAED,wBAAgB,MAAM,CACpB,OAAO,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,EACnF,SAAS,EAAE,OAAO,GAAG,MAAM,EAC3B,OAAO,CAAC,EAAE;IACR,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,KAAK,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,OAAO,CAAC;YAAE,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAA;SAAE,CAAC,CAAC;KACpF,CAAC,CAAC;CACJ,GACA,IAAI,CAmFN;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,EAAE,SAAS,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAE9F;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI,CAE9C;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,IAAI,UAAU,CAEjE;AAED,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,OAAO,EAAE,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import { renderToString, getHandler, clearHandlers } from './helpers/render.js';
2
2
  import { getSignalByIndex } from '../signals/helpers/core.js';
3
3
  import { matchRoute } from './helpers/match.js';
4
+ import { hydrateLazyInView } from '../viewport/index.js';
4
5
  export function createElement(type, props, ...children) {
5
6
  const resolvedProps = props ?? {};
6
7
  const flatChildren = children.flat().filter((child) => child != null && child !== false);
@@ -12,7 +13,7 @@ export function createElement(type, props, ...children) {
12
13
  props: resolvedProps,
13
14
  };
14
15
  }
15
- function attachEventHandlers(container) {
16
+ export function attachEventHandlers(container) {
16
17
  const elements = container.querySelectorAll('[data-ekclick]');
17
18
  elements.forEach((el) => {
18
19
  const id = el.getAttribute('data-ekclick');
@@ -68,10 +69,10 @@ function renderToTarget(layout, target, routeComponent, routeProps) {
68
69
  };
69
70
  const html = renderToString(jsxElement);
70
71
  target.innerHTML = html;
71
- attachEventHandlers(target);
72
- hydrateSignalBindings(target);
72
+ hydrateSubtree(target);
73
+ hydrateLazyInView(target);
73
74
  }
74
- function hydrateSignalBindings(container) {
75
+ export function hydrateSignalBindings(container) {
75
76
  const els = container.querySelectorAll('[data-ek-bind]');
76
77
  els.forEach((el) => {
77
78
  const idx = parseInt(el.getAttribute('data-ek-bind') ?? '', 10);
@@ -130,6 +131,10 @@ function hydrateSignalBindings(container) {
130
131
  });
131
132
  });
132
133
  }
134
+ export function hydrateSubtree(container) {
135
+ attachEventHandlers(container);
136
+ hydrateSignalBindings(container);
137
+ }
133
138
  export function render(element, container, options) {
134
139
  if (!element)
135
140
  return;
@@ -0,0 +1,2 @@
1
+ export declare function hydrateLazyInView(container: Element): void;
2
+ //# sourceMappingURL=hydrate-lazy-in-view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hydrate-lazy-in-view.d.ts","sourceRoot":"","sources":["../../src/viewport/hydrate-lazy-in-view.ts"],"names":[],"mappings":"AAsBA,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAwC1D"}
@@ -0,0 +1,41 @@
1
+ import { hydrateSubtree } from '../runtime/index.js';
2
+ import { renderToString } from '../runtime/helpers/render.js';
3
+ import { getLazyContent, unregisterLazyContent } from './registry.js';
4
+ import { observeOnce } from './observe-once.js';
5
+ function getLazyHosts(container) {
6
+ const hosts = [];
7
+ if (container.matches('[data-ek-lazy-in-view]:not([data-ek-lazy-loaded])')) {
8
+ hosts.push(container);
9
+ }
10
+ hosts.push(...Array.from(container.querySelectorAll('[data-ek-lazy-in-view]:not([data-ek-lazy-loaded])')));
11
+ return hosts;
12
+ }
13
+ export function hydrateLazyInView(container) {
14
+ const hosts = getLazyHosts(container);
15
+ hosts.forEach((host) => {
16
+ const id = host.getAttribute('data-ek-lazy-in-view');
17
+ const rootMargin = host.getAttribute('data-ek-lazy-root-margin') ?? '200px';
18
+ if (!id) {
19
+ return;
20
+ }
21
+ observeOnce(host, () => {
22
+ const loader = getLazyContent(id);
23
+ if (!loader) {
24
+ return;
25
+ }
26
+ const content = loader();
27
+ const html = content == null || content === false
28
+ ? ''
29
+ : typeof content === 'string' || typeof content === 'number'
30
+ ? String(content)
31
+ : renderToString(content);
32
+ host.innerHTML = html;
33
+ host.setAttribute('data-ek-lazy-loaded', 'true');
34
+ host.removeAttribute('aria-busy');
35
+ hydrateSubtree(host);
36
+ if (host.getAttribute('data-ek-lazy-once') !== 'false') {
37
+ unregisterLazyContent(id);
38
+ }
39
+ }, { rootMargin });
40
+ });
41
+ }
@@ -0,0 +1,5 @@
1
+ export * from './hydrate-lazy-in-view.js';
2
+ export * from './lazy-in-view.js';
3
+ export * from './observe-once.js';
4
+ export * from './registry.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/viewport/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from './hydrate-lazy-in-view.js';
2
+ export * from './lazy-in-view.js';
3
+ export * from './observe-once.js';
4
+ export * from './registry.js';
@@ -0,0 +1,13 @@
1
+ import type { JSXElementProps, JSXNode } from '../runtime/types.js';
2
+ export interface LazyInViewProps extends Omit<JSXElementProps, 'children'> {
3
+ as?: string;
4
+ children: JSXNode | (() => JSXNode);
5
+ className?: string;
6
+ fallback?: JSXNode;
7
+ minHeight?: number | string;
8
+ once?: boolean;
9
+ rootMargin?: string;
10
+ ssr?: 'lazy' | 'eager';
11
+ }
12
+ export declare function LazyInView({ as, children, className, fallback, minHeight, once, rootMargin, ssr, style, ...rest }: LazyInViewProps): JSXNode;
13
+ //# sourceMappingURL=lazy-in-view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lazy-in-view.d.ts","sourceRoot":"","sources":["../../src/viewport/lazy-in-view.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAGpE,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,eAAe,EAAE,UAAU,CAAC;IACxE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAMD,wBAAgB,UAAU,CAAC,EACzB,EAAU,EACV,QAAQ,EACR,SAAS,EACT,QAAe,EACf,SAAS,EACT,IAAW,EACX,UAAoB,EACpB,GAAY,EACZ,KAAK,EACL,GAAG,IAAI,EACR,EAAE,eAAe,GAAG,OAAO,CA6B3B"}
@@ -0,0 +1,28 @@
1
+ import { createElement } from '../runtime/index.js';
2
+ import { nextLazyId, registerLazyContent } from './registry.js';
3
+ function resolveLazyContent(children) {
4
+ return typeof children === 'function' ? children() : children;
5
+ }
6
+ export function LazyInView({ as = 'div', children, className, fallback = null, minHeight, once = true, rootMargin = '200px', ssr = 'lazy', style, ...rest }) {
7
+ const id = nextLazyId();
8
+ const loader = () => resolveLazyContent(children);
9
+ registerLazyContent(id, loader);
10
+ const shouldRenderLazy = ssr === 'lazy';
11
+ const resolvedStyle = minHeight == null
12
+ ? style
13
+ : {
14
+ ...(typeof style === 'object' && style !== null ? style : {}),
15
+ minHeight,
16
+ };
17
+ return createElement(as, {
18
+ ...rest,
19
+ 'aria-busy': shouldRenderLazy ? 'true' : undefined,
20
+ className,
21
+ 'data-ek-lazy-in-view': id,
22
+ 'data-ek-lazy-once': String(once),
23
+ 'data-ek-lazy-root-margin': rootMargin,
24
+ 'data-ek-lazy-loaded': shouldRenderLazy ? undefined : 'true',
25
+ style: resolvedStyle,
26
+ }, shouldRenderLazy ? fallback : loader());
27
+ }
28
+ ;
@@ -0,0 +1,6 @@
1
+ export interface ObserveOnceOptions {
2
+ rootMargin?: string;
3
+ threshold?: number;
4
+ }
5
+ export declare function observeOnce(element: Element, callback: () => void, options?: ObserveOnceOptions): () => void;
6
+ //# sourceMappingURL=observe-once.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observe-once.d.ts","sourceRoot":"","sources":["../../src/viewport/observe-once.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,WAAW,CACzB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,MAAM,IAAI,EACpB,OAAO,GAAE,kBAAuB,GAC/B,MAAM,IAAI,CA0BZ"}
@@ -0,0 +1,20 @@
1
+ export function observeOnce(element, callback, options = {}) {
2
+ if (typeof IntersectionObserver === 'undefined') {
3
+ callback();
4
+ return () => { };
5
+ }
6
+ const observer = new IntersectionObserver((entries) => {
7
+ if (!entries[0]?.isIntersecting) {
8
+ return;
9
+ }
10
+ observer.disconnect();
11
+ callback();
12
+ }, {
13
+ rootMargin: options.rootMargin,
14
+ threshold: options.threshold,
15
+ });
16
+ observer.observe(element);
17
+ return () => {
18
+ observer.disconnect();
19
+ };
20
+ }
@@ -0,0 +1,7 @@
1
+ import type { JSXNode } from '../runtime/types.js';
2
+ export declare function registerLazyContent(id: string, loader: () => JSXNode): void;
3
+ export declare function getLazyContent(id: string): (() => JSXNode) | undefined;
4
+ export declare function unregisterLazyContent(id: string): void;
5
+ export declare function clearLazyRegistry(): void;
6
+ export declare function nextLazyId(): string;
7
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/viewport/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAMnD,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,OAAO,GAAG,IAAI,CAE3E;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,CAAC,MAAM,OAAO,CAAC,GAAG,SAAS,CAEtE;AAED,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAEtD;AAED,wBAAgB,iBAAiB,IAAI,IAAI,CAGxC;AAED,wBAAgB,UAAU,IAAI,MAAM,CAGnC"}
@@ -0,0 +1,19 @@
1
+ const lazyContentRegistry = new Map();
2
+ let lazyIdCounter = 0;
3
+ export function registerLazyContent(id, loader) {
4
+ lazyContentRegistry.set(id, loader);
5
+ }
6
+ export function getLazyContent(id) {
7
+ return lazyContentRegistry.get(id);
8
+ }
9
+ export function unregisterLazyContent(id) {
10
+ lazyContentRegistry.delete(id);
11
+ }
12
+ export function clearLazyRegistry() {
13
+ lazyContentRegistry.clear();
14
+ lazyIdCounter = 0;
15
+ }
16
+ export function nextLazyId() {
17
+ lazyIdCounter += 1;
18
+ return `ek-lazy-${lazyIdCounter}`;
19
+ }
@@ -103,7 +103,7 @@ export function emberkitVitePlugin(userOptions = {}) {
103
103
  return routesCode;
104
104
  }
105
105
  if (id === VIRTUAL_SSR_ENTRY) {
106
- return generateSSREntry();
106
+ return generateSSREntry(options.site);
107
107
  }
108
108
  return null;
109
109
  },
@@ -1129,10 +1129,26 @@ function processParagraphs(html, breaks) {
1129
1129
  })
1130
1130
  .join('');
1131
1131
  }
1132
- function generateSSREntry() {
1132
+ function siteConfigToHeadOptions(site) {
1133
+ if (!site?.url) {
1134
+ return 'null';
1135
+ }
1136
+ return JSON.stringify({
1137
+ siteUrl: site.url,
1138
+ siteName: site.name,
1139
+ titleSuffix: site.titleSuffix,
1140
+ defaultDescription: site.description,
1141
+ defaultOgImage: site.ogImage,
1142
+ twitterSite: site.twitterSite,
1143
+ });
1144
+ }
1145
+ function generateSSREntry(site) {
1146
+ const siteHeadOptions = siteConfigToHeadOptions(site);
1133
1147
  return `
1134
1148
  import { routes, notFoundRoute, errorRoute } from 'virtual:emberkit-routes';
1135
- import { createElement } from '@emberkit/core';
1149
+ import { createElement, buildRouteHeadFromMetadata } from '@emberkit/core';
1150
+
1151
+ const siteHeadOptions = ${siteHeadOptions};
1136
1152
 
1137
1153
  const matchRoute = (routes, pathname) => {
1138
1154
  const normalizedPath = pathname.replace(/\\/+$/, '') || '/';
@@ -1268,14 +1284,8 @@ export async function render(url, server) {
1268
1284
  const mod = await match.route.component();
1269
1285
  const Component = mod.default || mod;
1270
1286
 
1271
- // Get metadata if available
1272
1287
  if (mod.metadata) {
1273
- if (mod.metadata.title) {
1274
- headContent += '<title>' + escapeHtml(mod.metadata.title) + '</title>\\n';
1275
- }
1276
- if (mod.metadata.description) {
1277
- headContent += '<meta name="description" content="' + escapeHtml(mod.metadata.description) + '">\\n';
1278
- }
1288
+ headContent += buildRouteHeadFromMetadata(mod.metadata, pathname, siteHeadOptions ?? undefined) + '\\n';
1279
1289
  }
1280
1290
 
1281
1291
  const element = createElement(Component, { params: match.params });
@@ -1,5 +1,13 @@
1
1
  import type { Plugin } from 'vite';
2
2
  export type EmberKitMode = 'static' | 'ssr' | 'spa' | 'hybrid';
3
+ export interface SiteConfig {
4
+ url: string;
5
+ name?: string;
6
+ titleSuffix?: string;
7
+ description?: string;
8
+ ogImage?: string;
9
+ twitterSite?: string;
10
+ }
3
11
  export interface EmberKitPluginOptions {
4
12
  mode?: EmberKitMode;
5
13
  routeDir?: string;
@@ -7,6 +15,7 @@ export interface EmberKitPluginOptions {
7
15
  jsx?: 'automatic' | 'classic';
8
16
  markdown?: Partial<MarkdownConfig>;
9
17
  mdx?: MDXConfig;
18
+ site?: SiteConfig;
10
19
  compression?: {
11
20
  gzip?: boolean;
12
21
  brotli?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/vite-plugin/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAGnC,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,KAAK,GAAG,KAAK,GAAG,QAAQ,CAAC;AAE/D,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IACnC,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,WAAW,CAAC,EAAE;QACZ,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,CAAC;CACH;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,OAAO,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,CAAC,EAAE,qBAAqB,KAAK,MAAM,CAAC;AAEzE,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;CAgBjB,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,OAAO,cAAc,GAAG,qBAAqB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/vite-plugin/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAGnC,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,KAAK,GAAG,KAAK,GAAG,QAAQ,CAAC;AAE/D,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IACnC,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,WAAW,CAAC,EAAE;QACZ,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,CAAC;CACH;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,OAAO,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,CAAC,EAAE,qBAAqB,KAAK,MAAM,CAAC;AAEzE,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;CAgBjB,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,OAAO,cAAc,GAAG,qBAAqB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@emberkit/core",
3
- "version": "0.4.2",
3
+ "version": "0.6.0",
4
4
  "type": "module",
5
5
  "private": false,
6
6
  "description": "Lightweight TypeScript-first JSX framework core",