@trypattern/sdk 0.1.0 → 0.1.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/api.d.ts +17 -7
- package/dist/api.js +34 -8
- package/dist/app.d.ts +12 -3
- package/dist/app.js +49 -7
- package/dist/appInfo.d.ts +35 -0
- package/dist/appInfo.js +67 -0
- package/dist/appTitle.d.ts +6 -0
- package/dist/appTitle.js +3 -0
- package/dist/builtins/AppSettings.d.ts +12 -0
- package/dist/builtins/AppSettings.js +31 -0
- package/dist/builtins/Toasts.d.ts +1 -1
- package/dist/builtins/Toasts.js +2 -1
- package/dist/cli/app.js +91 -14
- package/dist/cli/publishing.d.ts +21 -0
- package/dist/cli/publishing.js +493 -0
- package/dist/clock.d.ts +6 -0
- package/dist/clock.js +31 -0
- package/dist/components/AppFrame.js +3 -3
- package/dist/components/Button.d.ts +2 -1
- package/dist/components/Button.js +6 -3
- package/dist/components/CopyButton.d.ts +11 -0
- package/dist/components/CopyButton.js +16 -0
- package/dist/components/Divider.d.ts +2 -1
- package/dist/components/Divider.js +19 -4
- package/dist/components/IconButton.js +2 -2
- package/dist/components/Link.d.ts +8 -3
- package/dist/components/Link.js +11 -2
- package/dist/components/ListRow.js +2 -2
- package/dist/components/Menu.js +2 -2
- package/dist/components/RadioGroup.d.ts +18 -0
- package/dist/components/RadioGroup.js +85 -0
- package/dist/components/SegmentedControl.js +2 -2
- package/dist/components/Sidebar.js +2 -3
- package/dist/components/SignInScreen.js +3 -3
- package/dist/components/Switch.js +2 -1
- package/dist/components/controlLook.d.ts +10 -0
- package/dist/components/controlLook.js +14 -1
- package/dist/components/icons.d.ts +4 -3
- package/dist/components/icons.js +9 -3
- package/dist/components/interaction.d.ts +1 -1
- package/dist/flows/accessFlows.js +19 -3
- package/dist/flows/browser.d.ts +3 -1
- package/dist/flows/browser.js +6 -3
- package/dist/flows/flowBrowser.d.ts +3 -1
- package/dist/flows/flowBrowser.js +4 -2
- package/dist/flows/flows.d.ts +6 -0
- package/dist/flows/flows.js +32 -5
- package/dist/hooks/appContext.d.ts +2 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.js +4 -2
- package/dist/publishWire.d.ts +271 -0
- package/dist/publishWire.js +168 -0
- package/dist/react.d.ts +3 -0
- package/dist/react.js +2 -0
- package/dist/registered.d.ts +6 -0
- package/dist/registered.js +2 -0
- package/dist/rules/checkAllFiles.js +10 -2
- package/dist/rules/lintPlugin.js +2 -0
- package/dist/rules/messages.d.ts +2 -2
- package/dist/rules/messages.js +2 -2
- package/dist/schema.d.ts +2 -0
- package/dist/schema.js +1 -0
- package/dist/server/auth.js +4 -1
- package/dist/server/createServer.d.ts +48 -3
- package/dist/server/createServer.js +25 -5
- package/dist/server/env.d.ts +2 -2
- package/dist/server/index.d.ts +6 -1
- package/dist/server/index.js +5 -1
- package/dist/server/services.d.ts +9 -0
- package/dist/server/services.js +47 -0
- package/dist/server/session.d.ts +1 -0
- package/dist/server/session.js +11 -0
- package/dist/server/settings.d.ts +49 -0
- package/dist/server/settings.js +25 -0
- package/dist/server/signInWire.d.ts +1 -0
- package/dist/server/signInWire.js +2 -1
- package/dist/serviceClients.d.ts +5 -0
- package/dist/serviceClients.js +70 -0
- package/dist/services.d.ts +53 -0
- package/dist/services.js +30 -0
- package/dist/start.js +30 -6
- package/dist/store.d.ts +5 -3
- package/dist/store.js +13 -3
- package/dist/table.d.ts +1 -1
- package/dist/vite/localWorker.d.ts +1 -1
- package/dist/vite/localWorker.js +5 -4
- package/dist/vite/projectFile.d.ts +9 -0
- package/dist/vite/projectFile.js +17 -0
- package/dist/vite/vite.d.ts +2 -1
- package/dist/vite/vite.js +10 -3
- package/package.json +5 -1
- package/presets/register.d.ts +2 -0
package/dist/start.js
CHANGED
|
@@ -8,12 +8,14 @@ import { browserApi } from "./api.js";
|
|
|
8
8
|
import { Cache } from "./cache.js";
|
|
9
9
|
import { setAppIcons } from "./components/icons.js";
|
|
10
10
|
import { setInteractionSink } from "./components/interaction.js";
|
|
11
|
+
import { manualClock, realClock } from "./clock.js";
|
|
11
12
|
import { Gate } from "./gate.js";
|
|
12
13
|
import { AppProvider } from "./hooks/appContext.js";
|
|
13
14
|
import { routeObjects } from "./routes.js";
|
|
14
15
|
import { borders, breakpoints, colors, controls, fontFeatures, fontSizes, fontWeights, fonts, iconSizes, lineHeights, radii, shadows, space, widths } from "./theme/tokens.stylex.js";
|
|
15
16
|
const TEST_SEED = 'patternSeed';
|
|
16
17
|
const TEST_ADMINS = 'patternAdmins';
|
|
18
|
+
const TEST_WORLD = 'patternWorld';
|
|
17
19
|
function testSeed() {
|
|
18
20
|
const seed = Reflect.get(window, TEST_SEED);
|
|
19
21
|
return typeof seed === 'object' && seed !== null ? seed : {};
|
|
@@ -32,20 +34,26 @@ export function startApp(App, { theme = [], icons = {}, onInteraction } = {}) {
|
|
|
32
34
|
const gate = new Gate(testParams.getAll('fail'));
|
|
33
35
|
for (const call of testParams.getAll('hold'))
|
|
34
36
|
gate.hold(call);
|
|
35
|
-
const { tables, routes } = App.definition;
|
|
37
|
+
const { tables, routes, services, memory } = App.definition;
|
|
36
38
|
const inMemory = testParams.has('memory');
|
|
39
|
+
const world = inMemory ? (Reflect.get(window, TEST_WORLD) ?? {}) : {};
|
|
37
40
|
const router = createBrowserRouter(routeObjects(routes));
|
|
38
41
|
const app = new App(router, {
|
|
39
42
|
api: browserApi(tables, inMemory ? testSeed() : {}, gate, {
|
|
40
43
|
inMemory,
|
|
41
|
-
admins: inMemory ? testAdmins() : []
|
|
44
|
+
admins: inMemory ? testAdmins() : [],
|
|
45
|
+
...(services === undefined ? {} : { services }),
|
|
46
|
+
...(memory === undefined ? {} : { memory }),
|
|
47
|
+
world
|
|
42
48
|
}),
|
|
43
49
|
cache: Cache.local(),
|
|
44
|
-
gate
|
|
50
|
+
gate,
|
|
51
|
+
clock: inMemory ? manualClock() : realClock()
|
|
45
52
|
});
|
|
46
53
|
if (hot)
|
|
47
|
-
exposeToDevTools(app, gate, hot);
|
|
54
|
+
exposeToDevTools(app, gate, hot, world);
|
|
48
55
|
followAppearance(app);
|
|
56
|
+
followTitle(app);
|
|
49
57
|
if (onInteraction !== undefined) {
|
|
50
58
|
setInteractionSink((interaction) => onInteraction({
|
|
51
59
|
...interaction,
|
|
@@ -71,7 +79,17 @@ function followAppearance(app) {
|
|
|
71
79
|
account.subscribe(apply);
|
|
72
80
|
apply();
|
|
73
81
|
}
|
|
74
|
-
function
|
|
82
|
+
function followTitle(app) {
|
|
83
|
+
const store = app.stores.app;
|
|
84
|
+
const apply = () => {
|
|
85
|
+
const { title } = store.currentState;
|
|
86
|
+
if (title !== '')
|
|
87
|
+
document.title = title;
|
|
88
|
+
};
|
|
89
|
+
store.subscribe(apply);
|
|
90
|
+
apply();
|
|
91
|
+
}
|
|
92
|
+
function exposeToDevTools(app, gate, hot, world) {
|
|
75
93
|
async function snapshotWhenIdle() {
|
|
76
94
|
await app.whenIdle();
|
|
77
95
|
return app.getSnapshot();
|
|
@@ -89,7 +107,13 @@ function exposeToDevTools(app, gate, hot) {
|
|
|
89
107
|
send: dispatch,
|
|
90
108
|
snapshot: snapshotWhenIdle,
|
|
91
109
|
hold: (call) => gate.hold(call),
|
|
92
|
-
release: (call) => gate.release(call)
|
|
110
|
+
release: (call) => gate.release(call),
|
|
111
|
+
tick: () => app.tick(),
|
|
112
|
+
world: (patch) => {
|
|
113
|
+
if (typeof world === 'object' && world !== null) {
|
|
114
|
+
Object.assign(world, patch);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
93
117
|
}
|
|
94
118
|
});
|
|
95
119
|
if (navigator.webdriver)
|
package/dist/store.d.ts
CHANGED
|
@@ -26,13 +26,15 @@ export type StoreConfig<S extends StateSpec, P extends readonly (keyof S & strin
|
|
|
26
26
|
state?: S;
|
|
27
27
|
persist?: P;
|
|
28
28
|
};
|
|
29
|
-
export declare abstract class DeclaredStore<State extends object
|
|
29
|
+
export declare abstract class DeclaredStore<State extends object, Client = Record<never, never>> extends StoreBase<State> {
|
|
30
|
+
protected readonly services: Client;
|
|
31
|
+
constructor(services: Client);
|
|
30
32
|
protected initialState(): State;
|
|
31
33
|
}
|
|
32
|
-
export type StoreClass<S extends StateSpec, P extends readonly (keyof S & string)[]
|
|
34
|
+
export type StoreClass<S extends StateSpec, P extends readonly (keyof S & string)[], Client = Record<never, never>> = (abstract new (persisted: Persisted, services: Client) => DeclaredStore<StateOf<S>, Client>) & {
|
|
33
35
|
readonly config: StoreConfig<S, P>;
|
|
34
36
|
};
|
|
35
|
-
export declare function
|
|
37
|
+
export declare function defineStore<Client>(): <S extends StateSpec = Record<never, never>, const P extends readonly (keyof S & string)[] = []>(config: StoreConfig<S, P>) => StoreClass<S, P, Client>;
|
|
36
38
|
export type Snapshots<Group> = {
|
|
37
39
|
[Key in keyof Group]: Group[Key] extends {
|
|
38
40
|
readonly state: infer State;
|
package/dist/store.js
CHANGED
|
@@ -163,17 +163,27 @@ export class StoreBase {
|
|
|
163
163
|
}
|
|
164
164
|
}
|
|
165
165
|
export class DeclaredStore extends StoreBase {
|
|
166
|
+
services;
|
|
167
|
+
constructor(services) {
|
|
168
|
+
super();
|
|
169
|
+
this.services = services;
|
|
170
|
+
}
|
|
166
171
|
initialState() {
|
|
167
172
|
throw new Error(`${this.constructor.name} must extend Store({ state }) so its first state comes from the config`);
|
|
168
173
|
}
|
|
169
174
|
}
|
|
170
|
-
export function
|
|
175
|
+
export function defineStore() {
|
|
176
|
+
return function Store(config) {
|
|
177
|
+
return declaredStore(config);
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
function declaredStore(config) {
|
|
171
181
|
const persist = config.persist ?? [];
|
|
172
182
|
class Declared extends DeclaredStore {
|
|
173
183
|
static config = config;
|
|
174
184
|
#persisted;
|
|
175
|
-
constructor(persisted) {
|
|
176
|
-
super();
|
|
185
|
+
constructor(persisted, services) {
|
|
186
|
+
super(services);
|
|
177
187
|
this.#persisted = persisted;
|
|
178
188
|
}
|
|
179
189
|
initialState() {
|
package/dist/table.d.ts
CHANGED
|
@@ -134,7 +134,7 @@ type CheckedColumns<C> = {
|
|
|
134
134
|
type CheckedTable<Definition> = {
|
|
135
135
|
[Key in keyof Definition]: Key extends 'columns' ? CheckedColumns<SameOnTheWire<Definition[Key] & z.ZodRawShape>> : Key extends 'access' ? CheckedAccess<Definition, Definition[Key]> : Key extends 'writes' ? HasUnique<Definition> extends true ? Definition[Key] extends 'confirmed' ? Definition[Key] : UniqueNeedsConfirmed : Definition[Key] : Key extends 'public' ? ReadOf<Definition> extends 'anyone' ? PublicNeedsPrivateRead : Definition[Key] & readonly (ColumnOf<Definition> | 'createdAt')[] : Key extends 'unique' ? Definition[Key] & readonly (readonly ColumnOf<Definition>[])[] : Definition[Key];
|
|
136
136
|
} & Missing<Definition, 'access', AccessIsRequired> & Missing<Definition, 'writes', WritesIsRequired>;
|
|
137
|
-
export declare function defineTables<const Definitions extends Record<string, DraftTable>>(definitions: {
|
|
137
|
+
export declare function defineTables<const Definitions extends Record<string, DraftTable> = Record<never, never>>(definitions: {
|
|
138
138
|
[Key in keyof Definitions]: CheckedTable<Definitions[Key]>;
|
|
139
139
|
}): TablesOf<Definitions>;
|
|
140
140
|
export declare function ownerIdOf(email: string): string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { Plugin } from 'vite';
|
|
2
2
|
import type { Seed, Tables } from '../table.ts';
|
|
3
3
|
export declare function resetLocalDatabase(root: string, tables: Tables, seed: Seed<Tables>): void;
|
|
4
|
-
export declare function localWorker<Group extends Tables>(tables: Group, seed: Seed<Group
|
|
4
|
+
export declare function localWorker<Group extends Tables>(tables: Group, seed: Seed<Group>, title: string): Plugin;
|
package/dist/vite/localWorker.js
CHANGED
|
@@ -2,6 +2,7 @@ import { execFileSync } from 'node:child_process';
|
|
|
2
2
|
import { randomBytes } from 'node:crypto';
|
|
3
3
|
import { appendFileSync, existsSync, readFileSync } from 'node:fs';
|
|
4
4
|
import { join } from 'node:path';
|
|
5
|
+
import { seedTitleSql } from "../server/settings.js";
|
|
5
6
|
import { seedSql } from "../server/tables.js";
|
|
6
7
|
import { snakeCase } from "../table.js";
|
|
7
8
|
import { toolBin } from "../cli/tools.js";
|
|
@@ -34,7 +35,7 @@ export function resetLocalDatabase(root, tables, seed) {
|
|
|
34
35
|
].join('\n')
|
|
35
36
|
]);
|
|
36
37
|
}
|
|
37
|
-
function prepareLocalDatabase(root, tables, seed) {
|
|
38
|
+
function prepareLocalDatabase(root, tables, seed, title) {
|
|
38
39
|
wrangler(root, ['d1', 'migrations', 'apply', 'DB', '--local']);
|
|
39
40
|
wrangler(root, [
|
|
40
41
|
'd1',
|
|
@@ -42,10 +43,10 @@ function prepareLocalDatabase(root, tables, seed) {
|
|
|
42
43
|
'DB',
|
|
43
44
|
'--local',
|
|
44
45
|
'--command',
|
|
45
|
-
seedSql(tables, seed)
|
|
46
|
+
[seedTitleSql(title), seedSql(tables, seed)].join('\n')
|
|
46
47
|
]);
|
|
47
48
|
}
|
|
48
|
-
export function localWorker(tables, seed) {
|
|
49
|
+
export function localWorker(tables, seed, title) {
|
|
49
50
|
return {
|
|
50
51
|
name: 'pattern-local-worker',
|
|
51
52
|
config(config, { command }) {
|
|
@@ -53,7 +54,7 @@ export function localWorker(tables, seed) {
|
|
|
53
54
|
return;
|
|
54
55
|
const root = config.root ?? process.cwd();
|
|
55
56
|
ensureLocalSessionSecret(root);
|
|
56
|
-
prepareLocalDatabase(root, tables, seed);
|
|
57
|
+
prepareLocalDatabase(root, tables, seed, title);
|
|
57
58
|
}
|
|
58
59
|
};
|
|
59
60
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const PROJECT_FILE = "pattern.json";
|
|
3
|
+
declare const projectFile: z.ZodObject<{
|
|
4
|
+
name: z.ZodString;
|
|
5
|
+
title: z.ZodString;
|
|
6
|
+
}, z.core.$strip>;
|
|
7
|
+
export type ProjectFile = z.output<typeof projectFile>;
|
|
8
|
+
export declare function readProjectFile(root: string): ProjectFile;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { appTitle } from "../appTitle.js";
|
|
5
|
+
export const PROJECT_FILE = 'pattern.json';
|
|
6
|
+
const projectFile = z.object({ name: z.string().min(1), title: appTitle });
|
|
7
|
+
export function readProjectFile(root) {
|
|
8
|
+
const path = join(root, PROJECT_FILE);
|
|
9
|
+
if (!existsSync(path)) {
|
|
10
|
+
throw new Error(`${PROJECT_FILE} is missing. It holds the app's address and title: { "name": "acme", "title": "Acme" }`);
|
|
11
|
+
}
|
|
12
|
+
const parsed = projectFile.safeParse(JSON.parse(readFileSync(path, 'utf8')));
|
|
13
|
+
if (!parsed.success) {
|
|
14
|
+
throw new Error(`${PROJECT_FILE} needs "name" (the address) and "title" (1 to 60 characters): ${z.prettifyError(parsed.error)}`);
|
|
15
|
+
}
|
|
16
|
+
return parsed.data;
|
|
17
|
+
}
|
package/dist/vite/vite.d.ts
CHANGED
|
@@ -3,5 +3,6 @@ export type PatternOptions<Group extends Tables> = {
|
|
|
3
3
|
tables: Group;
|
|
4
4
|
admins: readonly string[];
|
|
5
5
|
seed?: Seed<Group>;
|
|
6
|
+
world?: object;
|
|
6
7
|
};
|
|
7
|
-
export declare function pattern<Group extends Tables>({ tables, admins, seed }: PatternOptions<Group>): import("vite").UserConfig;
|
|
8
|
+
export declare function pattern<Group extends Tables>({ tables, admins, seed, world }: PatternOptions<Group>): import("vite").UserConfig;
|
package/dist/vite/vite.js
CHANGED
|
@@ -8,6 +8,7 @@ import { defineConfig } from 'vitest/config';
|
|
|
8
8
|
import { commandBridge } from "./commandBridge.js";
|
|
9
9
|
import { designManifest } from "./designManifest.js";
|
|
10
10
|
import { localWorker } from "./localWorker.js";
|
|
11
|
+
import { readProjectFile } from "./projectFile.js";
|
|
11
12
|
import { rootAlias } from "./rootAlias.js";
|
|
12
13
|
const DEV_SERVER_PORT = 5173;
|
|
13
14
|
const VISUAL_FLOW_TIMEOUT_MS = 30_000;
|
|
@@ -25,8 +26,9 @@ const reactCompilerSkippingUnchangedRendersAndLoggingWhereItCannot = {
|
|
|
25
26
|
compiler: { logDiagnostics: true }
|
|
26
27
|
};
|
|
27
28
|
const FLOW_SETUP = fileURLToPath(new URL(`../flows/flowSetup${extname(import.meta.filename)}`, import.meta.url));
|
|
28
|
-
export function pattern({ tables, admins, seed = {} }) {
|
|
29
|
+
export function pattern({ tables, admins, seed = {}, world = {} }) {
|
|
29
30
|
const isVitest = process.env['VITEST'] !== undefined;
|
|
31
|
+
const { title } = readProjectFile(process.cwd());
|
|
30
32
|
const isVisualFlowRun = process.env['PATTERN_VISUAL_URL'] !== undefined;
|
|
31
33
|
const stylexPlugin = stylex.vite({
|
|
32
34
|
useCSSLayers: { before: CSS_LAYERS_BEFORE_STYLEX },
|
|
@@ -46,7 +48,7 @@ export function pattern({ tables, admins, seed = {} }) {
|
|
|
46
48
|
];
|
|
47
49
|
const workerServingApiInDevAndBuild = isVitest
|
|
48
50
|
? []
|
|
49
|
-
: [localWorker(tables, seed), cloudflare()];
|
|
51
|
+
: [localWorker(tables, seed, title), cloudflare()];
|
|
50
52
|
return defineConfig({
|
|
51
53
|
plugins: [
|
|
52
54
|
...stylexBeforeReactToKeepFastRefresh,
|
|
@@ -67,7 +69,12 @@ export function pattern({ tables, admins, seed = {} }) {
|
|
|
67
69
|
test: {
|
|
68
70
|
include: ['flows/**/*.flow.ts'],
|
|
69
71
|
server: { deps: { inline: ['@trypattern/sdk'] } },
|
|
70
|
-
provide: {
|
|
72
|
+
provide: {
|
|
73
|
+
patternSeed: seed,
|
|
74
|
+
patternAdmins: admins,
|
|
75
|
+
patternTitle: title,
|
|
76
|
+
patternWorld: world
|
|
77
|
+
},
|
|
71
78
|
...(isVisualFlowRun && {
|
|
72
79
|
globalSetup: [FLOW_SETUP],
|
|
73
80
|
testTimeout: VISUAL_FLOW_TIMEOUT_MS
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trypattern/sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -26,6 +26,10 @@
|
|
|
26
26
|
"types": "./dist/server/index.d.ts",
|
|
27
27
|
"default": "./dist/server/index.js"
|
|
28
28
|
},
|
|
29
|
+
"./publish": {
|
|
30
|
+
"types": "./dist/publishWire.d.ts",
|
|
31
|
+
"default": "./dist/publishWire.js"
|
|
32
|
+
},
|
|
29
33
|
"./flows": {
|
|
30
34
|
"types": "./dist/flows/flows.d.ts",
|
|
31
35
|
"default": "./dist/flows/flows.js"
|
package/presets/register.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { tables } from '@/schema.ts'
|
|
|
4
4
|
import type { actionGroups } from '@/src/actions/index.ts'
|
|
5
5
|
import type { models } from '@/src/models/index.ts'
|
|
6
6
|
import type { routes } from '@/src/routes.tsx'
|
|
7
|
+
import type { services } from '@/src/services/index.ts'
|
|
7
8
|
import type { stores } from '@/src/stores/index.ts'
|
|
8
9
|
import type { icons } from '@/src/theme/icons.ts'
|
|
9
10
|
|
|
@@ -14,6 +15,7 @@ declare module '@trypattern/sdk' {
|
|
|
14
15
|
tables: typeof tables
|
|
15
16
|
stores: typeof stores
|
|
16
17
|
routes: typeof routes
|
|
18
|
+
services: typeof services
|
|
17
19
|
icons: typeof icons
|
|
18
20
|
}
|
|
19
21
|
}
|