@ankhorage/zora 25.8.17 → 25.8.18

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 25.8.18
4
+
5
+ ### Patch Changes
6
+
7
+ - 8cce807: Publish SSR-safe `@ankhorage/zora/web/*` component and runtime entrypoints.
8
+
3
9
  ## 25.8.17
4
10
 
5
11
  ### Patch Changes
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  # @ankhorage/zora
5
5
 
6
- ![license: MIT](././paradox/badges/license.svg) ![npm: v25.8.17](././paradox/badges/npm.svg) ![runtime: bun](././paradox/badges/runtime.svg) ![typescript: strict](././paradox/badges/typescript.svg) ![eslint: checked](././paradox/badges/eslint.svg) ![prettier: checked](././paradox/badges/prettier.svg) ![build: checked](././paradox/badges/build.svg) ![tests: checked](././paradox/badges/tests.svg) ![paradox: warnings](././paradox/badges/docs.svg)
6
+ ![license: MIT](././paradox/badges/license.svg) ![npm: v25.8.18](././paradox/badges/npm.svg) ![runtime: bun](././paradox/badges/runtime.svg) ![typescript: strict](././paradox/badges/typescript.svg) ![eslint: checked](././paradox/badges/eslint.svg) ![prettier: checked](././paradox/badges/prettier.svg) ![build: checked](././paradox/badges/build.svg) ![tests: checked](././paradox/badges/tests.svg) ![paradox: warnings](././paradox/badges/docs.svg)
7
7
 
8
8
  Opinionated React Native and React Native Web UI kit built on @ankhorage/surface.
9
9
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ankhorage/zora",
3
3
  "type": "module",
4
- "version": "25.8.17",
4
+ "version": "25.8.18",
5
5
  "description": "Opinionated React Native and React Native Web UI kit built on @ankhorage/surface.",
6
6
  "homepage": "https://github.com/ankhorage/zora#readme",
7
7
  "bugs": {
@@ -120,6 +120,16 @@
120
120
  "import": "./dist/features/theme/public.js",
121
121
  "default": "./dist/features/theme/public.js"
122
122
  },
123
+ "./web/runtime": {
124
+ "types": "./web-dist/runtime/ZoraProvider.d.ts",
125
+ "import": "./web-dist/runtime/ZoraProvider.js",
126
+ "default": "./web-dist/runtime/ZoraProvider.js"
127
+ },
128
+ "./web/*": {
129
+ "types": "./web-dist/components/*/index.d.ts",
130
+ "import": "./web-dist/components/*/index.js",
131
+ "default": "./web-dist/components/*/index.js"
132
+ },
123
133
  "./package.json": "./package.json",
124
134
  "./cli": {
125
135
  "types": "./dist/cli/index.d.ts",
@@ -0,0 +1,101 @@
1
+ import { mkdtemp, rm, writeFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+
4
+ import { expect, test } from 'bun:test';
5
+ import React from 'react';
6
+ import { renderToStaticMarkup } from 'react-dom/server';
7
+
8
+ const forbiddenWebDependencies = [
9
+ 'expo-document-picker',
10
+ 'expo-image-picker',
11
+ '@gorhom/bottom-sheet',
12
+ 'react-native-gesture-handler',
13
+ ] as const;
14
+
15
+ /** Verifies that stable package web subpaths resolve only their requested UI graph. */
16
+ test('publishes SSR-safe ordinary UI through canonical web subpaths', async () => {
17
+ const packageJson = (await Bun.file('package.json').json()) as {
18
+ readonly exports: Record<string, unknown>;
19
+ };
20
+ expect(packageJson.exports['./web/runtime']).toEqual({
21
+ types: './web-dist/runtime/ZoraProvider.d.ts',
22
+ import: './web-dist/runtime/ZoraProvider.js',
23
+ default: './web-dist/runtime/ZoraProvider.js',
24
+ });
25
+ expect(packageJson.exports['./web/*']).toEqual({
26
+ types: './web-dist/components/*/index.d.ts',
27
+ import: './web-dist/components/*/index.js',
28
+ default: './web-dist/components/*/index.js',
29
+ });
30
+
31
+ const temporaryDirectory = await mkdtemp(join(process.cwd(), '.cache-zora-web-entrypoints-'));
32
+ try {
33
+ const entrypoint = join(temporaryDirectory, 'dashboard.tsx');
34
+ await writeFile(
35
+ entrypoint,
36
+ [
37
+ "export { ZoraProvider } from '@ankhorage/zora/web/runtime';",
38
+ "export { AppBar } from '@ankhorage/zora/web/app-bar';",
39
+ "export { AppShell } from '@ankhorage/zora/web/app-shell';",
40
+ "export { Badge } from '@ankhorage/zora/web/badge';",
41
+ "export { Button } from '@ankhorage/zora/web/button';",
42
+ "export { Card } from '@ankhorage/zora/web/card';",
43
+ "export { DataTable } from '@ankhorage/zora/web/data-table';",
44
+ "export { Dialog } from '@ankhorage/zora/web/dialog';",
45
+ "export { MetricCard } from '@ankhorage/zora/web/metric-card';",
46
+ "export { PopoverMenu } from '@ankhorage/zora/web/popover-menu';",
47
+ "export { Select } from '@ankhorage/zora/web/select';",
48
+ "export { TextInput } from '@ankhorage/zora/web/text-input';",
49
+ "export { Text } from '@ankhorage/zora/web/text';",
50
+ "export { Heading } from '@ankhorage/zora/web/heading';",
51
+ "export { View } from '@ankhorage/zora/web/view';",
52
+ '',
53
+ ].join('\n'),
54
+ 'utf8',
55
+ );
56
+
57
+ const build = await Bun.build({
58
+ entrypoints: [entrypoint],
59
+ target: 'browser',
60
+ format: 'esm',
61
+ external: ['react', 'react/*', 'react-dom', 'react-dom/*'],
62
+ });
63
+ expect(build.success).toBe(true);
64
+ const graph = (await Promise.all(build.outputs.map((output) => output.text()))).join('\n');
65
+ for (const dependency of forbiddenWebDependencies) {
66
+ expect(graph).not.toContain(dependency);
67
+ }
68
+ } finally {
69
+ await rm(temporaryDirectory, { force: true, recursive: true });
70
+ }
71
+ });
72
+
73
+ /** Renders the generated public web entrypoints without a native runtime host. */
74
+ test('SSR-renders ordinary UI from its public web subpaths', async () => {
75
+ const [{ ZoraProvider }, { AppShell }, { Button }, { Screen }, { Text }] = await Promise.all([
76
+ import('@ankhorage/zora/web/runtime'),
77
+ import('@ankhorage/zora/web/app-shell'),
78
+ import('@ankhorage/zora/web/button'),
79
+ import('@ankhorage/zora/web/screen'),
80
+ import('@ankhorage/zora/web/text'),
81
+ ]);
82
+ const markup = renderToStaticMarkup(
83
+ React.createElement(
84
+ ZoraProvider,
85
+ { mode: 'light' },
86
+ React.createElement(
87
+ AppShell,
88
+ undefined,
89
+ React.createElement(
90
+ Screen,
91
+ undefined,
92
+ React.createElement(Text, undefined, 'Web entrypoint'),
93
+ React.createElement(Button, undefined, 'Continue'),
94
+ ),
95
+ ),
96
+ ),
97
+ );
98
+
99
+ expect(markup).toContain('Web entrypoint');
100
+ expect(markup).toContain('Continue');
101
+ });