@usesidekick/react 0.1.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.
- package/README.md +246 -0
- package/dist/index.d.mts +358 -0
- package/dist/index.d.ts +358 -0
- package/dist/index.js +2470 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2403 -0
- package/dist/index.mjs.map +1 -0
- package/dist/jsx-dev-runtime.d.mts +21 -0
- package/dist/jsx-dev-runtime.d.ts +21 -0
- package/dist/jsx-dev-runtime.js +160 -0
- package/dist/jsx-dev-runtime.js.map +1 -0
- package/dist/jsx-dev-runtime.mjs +122 -0
- package/dist/jsx-dev-runtime.mjs.map +1 -0
- package/dist/jsx-runtime.d.mts +26 -0
- package/dist/jsx-runtime.d.ts +26 -0
- package/dist/jsx-runtime.js +150 -0
- package/dist/jsx-runtime.js.map +1 -0
- package/dist/jsx-runtime.mjs +109 -0
- package/dist/jsx-runtime.mjs.map +1 -0
- package/dist/server/index.d.mts +235 -0
- package/dist/server/index.d.ts +235 -0
- package/dist/server/index.js +642 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/index.mjs +597 -0
- package/dist/server/index.mjs.map +1 -0
- package/package.json +64 -0
- package/src/components/SidekickPanel.tsx +868 -0
- package/src/components/index.ts +1 -0
- package/src/context.tsx +157 -0
- package/src/flags.ts +47 -0
- package/src/index.ts +71 -0
- package/src/jsx-dev-runtime.ts +138 -0
- package/src/jsx-runtime.ts +159 -0
- package/src/loader.ts +35 -0
- package/src/primitives/behavior.ts +70 -0
- package/src/primitives/data.ts +91 -0
- package/src/primitives/index.ts +3 -0
- package/src/primitives/ui.ts +268 -0
- package/src/provider.tsx +1264 -0
- package/src/runtime-loader.ts +106 -0
- package/src/server/drizzle-adapter.ts +53 -0
- package/src/server/drizzle-schema.ts +16 -0
- package/src/server/generate.ts +578 -0
- package/src/server/handler.ts +343 -0
- package/src/server/index.ts +20 -0
- package/src/server/storage.ts +1 -0
- package/src/server/types.ts +49 -0
- package/src/types.ts +295 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { transform } from 'sucrase';
|
|
3
|
+
import { createOverride } from './loader';
|
|
4
|
+
import { SDK } from './types';
|
|
5
|
+
|
|
6
|
+
interface OverrideData {
|
|
7
|
+
id: string;
|
|
8
|
+
name: string;
|
|
9
|
+
description: string;
|
|
10
|
+
code: string;
|
|
11
|
+
enabled: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface LoadedOverride {
|
|
15
|
+
id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
description: string;
|
|
18
|
+
enabled: boolean;
|
|
19
|
+
activate: (sdk: SDK) => void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function compileOverride(overrideData: OverrideData): LoadedOverride | null {
|
|
23
|
+
try {
|
|
24
|
+
// Transform TypeScript/JSX to plain JavaScript
|
|
25
|
+
const transformed = transform(overrideData.code, {
|
|
26
|
+
transforms: ['typescript', 'jsx'],
|
|
27
|
+
jsxRuntime: 'classic',
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Create a module-like environment
|
|
31
|
+
const exports: { default?: ReturnType<typeof createOverride> } = {};
|
|
32
|
+
const require = (moduleName: string) => {
|
|
33
|
+
if (moduleName === 'react') return React;
|
|
34
|
+
if (moduleName === '@usesidekick/react') {
|
|
35
|
+
return { createOverride, SDK: {} };
|
|
36
|
+
}
|
|
37
|
+
throw new Error(`Module not found: ${moduleName}`);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// Execute the transformed code
|
|
41
|
+
// Prepend destructuring of common React exports so overrides can use
|
|
42
|
+
// bare names like useState, useEffect, etc. instead of React.useState
|
|
43
|
+
const reactDestructure = 'var { useState, useEffect, useCallback, useMemo, useRef, useContext, useReducer, memo, forwardRef, createContext, Fragment } = React;\n';
|
|
44
|
+
const moduleFunction = new Function(
|
|
45
|
+
'exports',
|
|
46
|
+
'require',
|
|
47
|
+
'React',
|
|
48
|
+
'createOverride',
|
|
49
|
+
reactDestructure + transformed.code.replace(
|
|
50
|
+
/import\s+.*?from\s+['"].*?['"]/g,
|
|
51
|
+
'' // Remove import statements, we inject dependencies
|
|
52
|
+
).replace(
|
|
53
|
+
/export\s+default\s+/,
|
|
54
|
+
'exports.default = '
|
|
55
|
+
)
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
moduleFunction(exports, require, React, createOverride);
|
|
59
|
+
|
|
60
|
+
if (!exports.default) {
|
|
61
|
+
console.error(`[Sidekick] Override ${overrideData.id} has no default export`);
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
id: overrideData.id,
|
|
67
|
+
name: overrideData.name,
|
|
68
|
+
description: overrideData.description,
|
|
69
|
+
enabled: overrideData.enabled,
|
|
70
|
+
activate: exports.default.activate,
|
|
71
|
+
};
|
|
72
|
+
} catch (error) {
|
|
73
|
+
console.error(`[Sidekick] Failed to compile override ${overrideData.id}:`, error);
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export async function fetchAndCompileOverrides(
|
|
79
|
+
endpoint: string
|
|
80
|
+
): Promise<LoadedOverride[]> {
|
|
81
|
+
try {
|
|
82
|
+
const response = await fetch(endpoint);
|
|
83
|
+
if (!response.ok) {
|
|
84
|
+
throw new Error(`Failed to fetch overrides: ${response.status}`);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const data = await response.json();
|
|
88
|
+
if (!data.success || !Array.isArray(data.overrides)) {
|
|
89
|
+
throw new Error('Invalid response format');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const compiled: LoadedOverride[] = [];
|
|
93
|
+
for (const override of data.overrides) {
|
|
94
|
+
// Compile all overrides (enabled or not) so they appear in the list
|
|
95
|
+
const loaded = compileOverride(override);
|
|
96
|
+
if (loaded) {
|
|
97
|
+
compiled.push(loaded);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return compiled;
|
|
102
|
+
} catch (error) {
|
|
103
|
+
console.error('[Sidekick] Failed to fetch overrides:', error);
|
|
104
|
+
return [];
|
|
105
|
+
}
|
|
106
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { eq } from 'drizzle-orm';
|
|
2
|
+
import type { SidekickStorage, OverrideRecord, NewOverrideRecord } from './types';
|
|
3
|
+
import type { sidekickOverrides as OverridesTable } from './drizzle-schema';
|
|
4
|
+
|
|
5
|
+
type DrizzleDb = {
|
|
6
|
+
select(): any;
|
|
7
|
+
insert(table: any): any;
|
|
8
|
+
update(table: any): any;
|
|
9
|
+
delete(table: any): any;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export function createDrizzleStorage(
|
|
13
|
+
db: DrizzleDb,
|
|
14
|
+
overridesTable: typeof OverridesTable
|
|
15
|
+
): SidekickStorage {
|
|
16
|
+
return {
|
|
17
|
+
async listOverrides(): Promise<OverrideRecord[]> {
|
|
18
|
+
const rows = await db.select().from(overridesTable).orderBy(overridesTable.createdAt);
|
|
19
|
+
return rows as OverrideRecord[];
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
async getOverride(id: string): Promise<OverrideRecord | null> {
|
|
23
|
+
const rows = await db.select().from(overridesTable).where(eq(overridesTable.id, id));
|
|
24
|
+
return (rows[0] as OverrideRecord) ?? null;
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
async createOverride(data: NewOverrideRecord): Promise<void> {
|
|
28
|
+
await db.insert(overridesTable).values({
|
|
29
|
+
id: data.id,
|
|
30
|
+
name: data.name,
|
|
31
|
+
description: data.description,
|
|
32
|
+
version: data.version,
|
|
33
|
+
primitives: data.primitives,
|
|
34
|
+
code: data.code,
|
|
35
|
+
enabled: data.enabled ?? true,
|
|
36
|
+
createdAt: data.createdAt ?? new Date(),
|
|
37
|
+
updatedAt: data.updatedAt ?? new Date(),
|
|
38
|
+
});
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
async updateOverride(id: string, data: Partial<OverrideRecord>): Promise<void> {
|
|
42
|
+
// Strip id and createdAt to prevent accidental PK/immutable field updates
|
|
43
|
+
const { id: _id, createdAt: _ca, ...updateData } = data;
|
|
44
|
+
await db.update(overridesTable)
|
|
45
|
+
.set({ ...updateData, updatedAt: new Date() })
|
|
46
|
+
.where(eq(overridesTable.id, id));
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
async deleteOverride(id: string): Promise<void> {
|
|
50
|
+
await db.delete(overridesTable).where(eq(overridesTable.id, id));
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { pgTable, text, timestamp, boolean } from 'drizzle-orm/pg-core';
|
|
2
|
+
|
|
3
|
+
export const sidekickOverrides = pgTable('overrides', {
|
|
4
|
+
id: text('id').primaryKey(),
|
|
5
|
+
name: text('name').notNull(),
|
|
6
|
+
description: text('description').notNull(),
|
|
7
|
+
version: text('version').notNull().default('1.0.0'),
|
|
8
|
+
primitives: text('primitives').notNull(), // JSON array stored as text
|
|
9
|
+
code: text('code').notNull(),
|
|
10
|
+
enabled: boolean('enabled').notNull().default(true),
|
|
11
|
+
createdAt: timestamp('created_at').defaultNow().notNull(),
|
|
12
|
+
updatedAt: timestamp('updated_at').defaultNow().notNull(),
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export type SidekickOverride = typeof sidekickOverrides.$inferSelect;
|
|
16
|
+
export type NewSidekickOverride = typeof sidekickOverrides.$inferInsert;
|