@emberkit/core 0.5.0 → 0.6.1

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.
package/dist/index.d.ts CHANGED
@@ -13,11 +13,11 @@ export { compileMDX, compileSync, useMDX } from './mdx/index.js';
13
13
  export { DataCache, createCache, getCached, setCache, prefetch } from './cache/index.js';
14
14
  export { LazyInView, hydrateLazyInView, clearLazyRegistry } from './viewport/index.js';
15
15
  export { renderToHTMLString } from './ssr/helpers/render-html.js';
16
- export { drainHeadContent } from './meta/head-registry.js';
16
+ export { drainHeadContent, clearHeadContent } from './meta/head-registry.js';
17
17
  export { Head } from './meta/index.js';
18
18
  export type { HeadProps } from './meta/index.js';
19
- export { generateMeta, generateBreadcrumbs, generateArticleSchema, generateProductSchema, } from './meta/index.js';
20
- 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';
21
21
  export type { FC, RouteComponent, RouteChildren, RouteParams } from './runtime/types.js';
22
22
  export type { LazyInViewProps } from './viewport/index.js';
23
23
  export type { Logger, LoggerOptions, LogLevel, RequestLog, ResponseLog } from './logger/types.js';
@@ -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;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,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;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"}
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,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC7E,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
@@ -12,9 +12,9 @@ export { compileMDX, compileSync, useMDX } from './mdx/index.js';
12
12
  export { DataCache, createCache, getCached, setCache, prefetch } from './cache/index.js';
13
13
  export { LazyInView, hydrateLazyInView, clearLazyRegistry } from './viewport/index.js';
14
14
  export { renderToHTMLString } from './ssr/helpers/render-html.js';
15
- export { drainHeadContent } from './meta/head-registry.js';
15
+ export { drainHeadContent, clearHeadContent } from './meta/head-registry.js';
16
16
  export { Head } from './meta/index.js';
17
- export { generateMeta, generateBreadcrumbs, generateArticleSchema, generateProductSchema, } from './meta/index.js';
17
+ export { generateMeta, buildRouteHeadFromMetadata, generateBreadcrumbs, generateArticleSchema, generateProductSchema, } from './meta/index.js';
18
18
  export function defineConfig(config) {
19
19
  return config;
20
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
+ }
@@ -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,44 @@ 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
- import { routes, notFoundRoute, errorRoute } from 'virtual:emberkit-routes';
1135
- import { createElement } from '@emberkit/core';
1148
+ import { routes, rootLayout, notFoundRoute, errorRoute } from 'virtual:emberkit-routes';
1149
+ import {
1150
+ createElement,
1151
+ buildRouteHeadFromMetadata,
1152
+ drainHeadContent,
1153
+ clearHeadContent,
1154
+ } from '@emberkit/core';
1155
+
1156
+ const siteHeadOptions = ${siteHeadOptions};
1157
+
1158
+ const wrapWithRootLayout = async (RouteComponent) => {
1159
+ if (!rootLayout) {
1160
+ return RouteComponent;
1161
+ }
1162
+ const layoutMod = await rootLayout();
1163
+ const Layout = layoutMod.default || layoutMod;
1164
+ return (routeProps) =>
1165
+ createElement(Layout, {
1166
+ pathname: routeProps?.pathname,
1167
+ children: createElement(RouteComponent, routeProps),
1168
+ });
1169
+ };
1136
1170
 
1137
1171
  const matchRoute = (routes, pathname) => {
1138
1172
  const normalizedPath = pathname.replace(/\\/+$/, '') || '/';
@@ -1266,20 +1300,18 @@ export async function render(url, server) {
1266
1300
  if (match) {
1267
1301
  try {
1268
1302
  const mod = await match.route.component();
1269
- const Component = mod.default || mod;
1270
-
1271
- // Get metadata if available
1303
+ const Route = mod.default || mod;
1304
+ clearHeadContent();
1305
+ const Page = await wrapWithRootLayout(Route);
1306
+ const element = createElement(Page, { params: match.params, pathname });
1307
+ appHtml = renderToString(element);
1308
+ const drained = drainHeadContent();
1272
1309
  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
- }
1310
+ headContent =
1311
+ buildRouteHeadFromMetadata(mod.metadata, pathname, siteHeadOptions ?? undefined) + '\\n';
1312
+ } else if (drained) {
1313
+ headContent = drained + '\\n';
1279
1314
  }
1280
-
1281
- const element = createElement(Component, { params: match.params });
1282
- appHtml = renderToString(element);
1283
1315
  } catch (e) {
1284
1316
  console.error('[SSR] Failed to render route:', pathname, e);
1285
1317
  if (errorRoute) {
@@ -1308,9 +1340,18 @@ export async function render(url, server) {
1308
1340
  if (notFoundRoute) {
1309
1341
  try {
1310
1342
  const mod = await notFoundRoute();
1311
- const Component = mod.default || mod;
1312
- const element = createElement(Component, { });
1343
+ const Route = mod.default || mod;
1344
+ clearHeadContent();
1345
+ const Page = await wrapWithRootLayout(Route);
1346
+ const element = createElement(Page, { });
1313
1347
  appHtml = renderToString(element);
1348
+ const drained = drainHeadContent();
1349
+ if (drained) {
1350
+ headContent = drained + '\\n';
1351
+ } else if (mod.metadata) {
1352
+ headContent =
1353
+ buildRouteHeadFromMetadata(mod.metadata, pathname, siteHeadOptions ?? undefined) + '\\n';
1354
+ }
1314
1355
  } catch (e) {
1315
1356
  console.error('[SSR] Failed to render 404 page:', e);
1316
1357
  appHtml = '<div style="padding: 20px;">404 - Page not found</div>';
@@ -1395,10 +1436,19 @@ function generateRoutesCode(files, routeDir) {
1395
1436
  const routeEntries = [];
1396
1437
  let notFoundRoute = 'null';
1397
1438
  let errorRoute = 'null';
1439
+ let rootLayout = 'null';
1398
1440
  for (const file of files) {
1399
1441
  const relativePath = relative(routeDir, file).replace(/\\/g, '/');
1400
1442
  const ext = file.split('.').pop() ?? '';
1401
1443
  const isMarkdown = ext === 'md' || ext === 'mdx';
1444
+ const importPath = file.replace(/\\/g, '/');
1445
+ if (relativePath === '_layout.tsx' ||
1446
+ relativePath === '_layout.ts' ||
1447
+ relativePath === '_layout.jsx' ||
1448
+ relativePath === '_layout.js') {
1449
+ rootLayout = `() => import(${JSON.stringify(importPath)})`;
1450
+ continue;
1451
+ }
1402
1452
  // Check for special error pages
1403
1453
  if (relativePath === '404.tsx' || relativePath === '404.ts' || relativePath === '404.jsx' || relativePath === '404.js') {
1404
1454
  const importPath = file.replace(/\\/g, '/');
@@ -1431,7 +1481,6 @@ function generateRoutesCode(files, routeDir) {
1431
1481
  else {
1432
1482
  routePath = '/' + routePath;
1433
1483
  }
1434
- const importPath = file.replace(/\\/g, '/');
1435
1484
  const entry = isMarkdown
1436
1485
  ? ` { path: ${JSON.stringify(routePath)}, component: () => import(${JSON.stringify(importPath)}), isMarkdown: true }`
1437
1486
  : ` { path: ${JSON.stringify(routePath)}, component: () => import(${JSON.stringify(importPath)}) }`;
@@ -1441,6 +1490,7 @@ function generateRoutesCode(files, routeDir) {
1441
1490
  // the correct priority order (defense-in-depth alongside runtime scoring).
1442
1491
  routeEntries.sort((a, b) => scoreRoutePath(b.path) - scoreRoutePath(a.path));
1443
1492
  return `export const routes = [\n${routeEntries.map((r) => r.entry).join(',\n')}\n];
1493
+ export const rootLayout = ${rootLayout};
1444
1494
  export const notFoundRoute = ${notFoundRoute};
1445
1495
  export const errorRoute = ${errorRoute};`;
1446
1496
  }
@@ -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.5.0",
3
+ "version": "0.6.1",
4
4
  "type": "module",
5
5
  "private": false,
6
6
  "description": "Lightweight TypeScript-first JSX framework core",