bleam 0.0.13 → 0.0.14
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/ai.cjs +1 -1
- package/dist/ai.d.ts +1 -1
- package/dist/ai.js +1 -1
- package/dist/cli.cjs +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/elements-DX_YUveu.d.ts +341 -0
- package/dist/elements-gEI8YGl1.d.cts +341 -0
- package/dist/elements.cjs +582 -54
- package/dist/elements.d.cts +2 -2
- package/dist/elements.d.ts +2 -2
- package/dist/elements.js +560 -55
- package/dist/files.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/schema.d.ts +1 -1
- package/dist/{state-BZYyrE2-.cjs → state-Bm9GiRnU.cjs} +58 -7
- package/dist/{state-DkaRFkZJ.js → state-D8Firo9w.js} +57 -7
- package/dist/state.cjs +1 -1
- package/dist/state.d.ts +1 -1
- package/dist/state.js +1 -1
- package/dist/window.d.cts +1 -1
- package/dist/window.d.ts +3 -3
- package/package.json +4 -6
- package/templates/basic/app/index.tsx +7 -129
- package/templates/foundation-models/app/index.tsx +100 -41
- package/templates/native/ios/Podfile.lock +6 -0
- package/templates/native/package.json +6 -1
- package/templates/native/yarn.lock +5392 -3749
- package/dist/elements-CFk0QHw0.d.cts +0 -127
- package/dist/elements-ClGQ41Sc.d.ts +0 -127
- package/dist/native-sqlite-Dw--FI9a.cjs +0 -66
- package/dist/native-sqlite-WzRNzCSh.js +0 -64
- /package/dist/{config-Cms0rvqg.d.ts → config-Chi-flpJ.d.ts} +0 -0
- /package/dist/{files-4ZEoAWiv.d.ts → files-VrkQlKIT.d.ts} +0 -0
- /package/dist/{schema-LxnzAfgw.d.ts → schema-DsXZBnvc.d.ts} +0 -0
package/dist/files.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as DownloadTask, c as FileStat, d as PickOptions, f as RemoveOptions, i as DownloadProgress, l as FileType, m as files, n as DirectoryRef, o as FilePaths, p as WriteOptions, r as DownloadOptions, s as FileRef, t as CreateDirectoryOptions, u as PickFileType } from "./files-
|
|
1
|
+
import { a as DownloadTask, c as FileStat, d as PickOptions, f as RemoveOptions, i as DownloadProgress, l as FileType, m as files, n as DirectoryRef, o as FilePaths, p as WriteOptions, r as DownloadOptions, s as FileRef, t as CreateDirectoryOptions, u as PickFileType } from "./files-VrkQlKIT.js";
|
|
2
2
|
export { CreateDirectoryOptions, DirectoryRef, DownloadOptions, DownloadProgress, DownloadTask, FilePaths, FileRef, FileStat, FileType, PickFileType, PickOptions, RemoveOptions, WriteOptions, files };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as HexColor, c as defineConfig, i as BleamUserInterfaceStyle, n as BleamConfig, o as appConfig, r as BleamInternalExpoConfig, s as createExpoConfig, t as BleamAppearance } from "./config-
|
|
1
|
+
import { a as HexColor, c as defineConfig, i as BleamUserInterfaceStyle, n as BleamConfig, o as appConfig, r as BleamInternalExpoConfig, s as createExpoConfig, t as BleamAppearance } from "./config-Chi-flpJ.js";
|
|
2
2
|
export { BleamAppearance, BleamConfig, BleamInternalExpoConfig, BleamUserInterfaceStyle, HexColor, appConfig, createExpoConfig, defineConfig };
|
package/dist/schema.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as array, C as SchemaOutput, D as StandardSchema, E as SchemaShape, F as number, I as object, L as schema, M as getFieldSchema, N as getValueAtPath, O as StringField, P as literal, R as string, S as SchemaJSONSchema, T as SchemaResult, _ as ObjectField, a as FieldAtFieldPath, b as SchemaInput, c as FieldPath, d as FieldValue, f as InferInput, g as NumberField, h as LiteralField, i as DeepPartial, j as boolean, k as ValueAtFieldPath, l as FieldSchema, m as JSONValue, n as BleamSchema, o as FieldInput, p as InferOutput, r as BooleanField, s as FieldOutput, t as ArrayField, u as FieldToken, v as PrimitiveValue, w as SchemaPatch, x as SchemaIssue, y as SchemaError } from "./schema-
|
|
1
|
+
import { A as array, C as SchemaOutput, D as StandardSchema, E as SchemaShape, F as number, I as object, L as schema, M as getFieldSchema, N as getValueAtPath, O as StringField, P as literal, R as string, S as SchemaJSONSchema, T as SchemaResult, _ as ObjectField, a as FieldAtFieldPath, b as SchemaInput, c as FieldPath, d as FieldValue, f as InferInput, g as NumberField, h as LiteralField, i as DeepPartial, j as boolean, k as ValueAtFieldPath, l as FieldSchema, m as JSONValue, n as BleamSchema, o as FieldInput, p as InferOutput, r as BooleanField, s as FieldOutput, t as ArrayField, u as FieldToken, v as PrimitiveValue, w as SchemaPatch, x as SchemaIssue, y as SchemaError } from "./schema-DsXZBnvc.js";
|
|
2
2
|
export { ArrayField, BleamSchema, BooleanField, DeepPartial, FieldAtFieldPath, FieldInput, FieldOutput, FieldPath, FieldSchema, FieldToken, FieldValue, InferInput, InferOutput, JSONValue, LiteralField, NumberField, ObjectField, PrimitiveValue, SchemaError, SchemaInput, SchemaIssue, SchemaJSONSchema, SchemaOutput, SchemaPatch, SchemaResult, SchemaShape, StandardSchema, StringField, ValueAtFieldPath, array, boolean, getFieldSchema, getValueAtPath, literal, number, object, schema, string };
|
|
@@ -8,6 +8,8 @@ let jotai_vanilla = require("jotai/vanilla");
|
|
|
8
8
|
jotai_vanilla = require_chunk.__toESM(jotai_vanilla);
|
|
9
9
|
let jotai_family = require("jotai-family");
|
|
10
10
|
jotai_family = require_chunk.__toESM(jotai_family);
|
|
11
|
+
let expo_sqlite = require("expo-sqlite");
|
|
12
|
+
expo_sqlite = require_chunk.__toESM(expo_sqlite);
|
|
11
13
|
|
|
12
14
|
//#region src/state/atom.ts
|
|
13
15
|
const storedAtomsKey = Symbol.for("bleam.state.storedAtoms.v1");
|
|
@@ -128,6 +130,55 @@ function internalJotaiWritableAtom(value) {
|
|
|
128
130
|
}
|
|
129
131
|
const internalStore = (0, jotai_vanilla.getDefaultStore)();
|
|
130
132
|
|
|
133
|
+
//#endregion
|
|
134
|
+
//#region src/native-sqlite.ts
|
|
135
|
+
const databases = /* @__PURE__ */ new Map();
|
|
136
|
+
function toExpoParameters(parameters) {
|
|
137
|
+
return parameters;
|
|
138
|
+
}
|
|
139
|
+
function toSQLiteValue(value) {
|
|
140
|
+
if (typeof value === "string" || typeof value === "number" || value === null) return value;
|
|
141
|
+
throw new Error("SQLite blobs are not supported by Bleam state yet");
|
|
142
|
+
}
|
|
143
|
+
function toSQLiteRow(row) {
|
|
144
|
+
const output = {};
|
|
145
|
+
for (const [key, value] of Object.entries(row)) output[key] = toSQLiteValue(value);
|
|
146
|
+
return output;
|
|
147
|
+
}
|
|
148
|
+
var NativeSQLiteDatabase = class NativeSQLiteDatabase {
|
|
149
|
+
constructor(database) {
|
|
150
|
+
this.database = database;
|
|
151
|
+
}
|
|
152
|
+
async execute(query, parameters) {
|
|
153
|
+
await this.database.runAsync(query, toExpoParameters(parameters) ?? []);
|
|
154
|
+
}
|
|
155
|
+
async select(query, parameters) {
|
|
156
|
+
return (await this.database.getAllAsync(query, toExpoParameters(parameters) ?? [])).map(toSQLiteRow);
|
|
157
|
+
}
|
|
158
|
+
async get(query, parameters) {
|
|
159
|
+
const row = await this.database.getFirstAsync(query, toExpoParameters(parameters) ?? []);
|
|
160
|
+
return row ? toSQLiteRow(row) : void 0;
|
|
161
|
+
}
|
|
162
|
+
async transaction(action) {
|
|
163
|
+
let result;
|
|
164
|
+
await this.database.withExclusiveTransactionAsync(async (transaction) => {
|
|
165
|
+
result = await action(new NativeSQLiteDatabase(transaction));
|
|
166
|
+
});
|
|
167
|
+
return result;
|
|
168
|
+
}
|
|
169
|
+
close() {
|
|
170
|
+
return this.database.closeAsync();
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
function openNativeSQLiteDatabase(name = "bleam.sqlite3") {
|
|
174
|
+
let database = databases.get(name);
|
|
175
|
+
if (!database) {
|
|
176
|
+
database = (0, expo_sqlite.openDatabaseAsync)(name).then((value) => new NativeSQLiteDatabase(value));
|
|
177
|
+
databases.set(name, database);
|
|
178
|
+
}
|
|
179
|
+
return database;
|
|
180
|
+
}
|
|
181
|
+
|
|
131
182
|
//#endregion
|
|
132
183
|
//#region src/state/collection.ts
|
|
133
184
|
var CollectionVersionConflictError = class extends Error {
|
|
@@ -155,18 +206,18 @@ let jsonSqlSupportPromise;
|
|
|
155
206
|
let mutationPipeline = Promise.resolve();
|
|
156
207
|
let transactionCallbackStarting = false;
|
|
157
208
|
function getDatabase() {
|
|
158
|
-
databasePromise ??= Promise.resolve().then(() =>
|
|
209
|
+
databasePromise ??= Promise.resolve().then(() => openNativeSQLiteDatabase(`${require_app_storage.currentAppStorageKey()}.sqlite3`));
|
|
159
210
|
return databasePromise;
|
|
160
211
|
}
|
|
161
212
|
async function initializedDatabase() {
|
|
162
213
|
initializedPromise ??= (async () => {
|
|
163
214
|
const database = await getDatabase();
|
|
164
215
|
await database.execute("PRAGMA journal_mode = WAL");
|
|
165
|
-
if (numberValue(await database.get("PRAGMA user_version"), "user_version", 0) !== schemaVersion) await database.transaction(async () => {
|
|
166
|
-
await
|
|
167
|
-
await
|
|
168
|
-
await createTables(
|
|
169
|
-
await
|
|
216
|
+
if (numberValue(await database.get("PRAGMA user_version"), "user_version", 0) !== schemaVersion) await database.transaction(async (transaction) => {
|
|
217
|
+
await transaction.execute("DROP TABLE IF EXISTS links");
|
|
218
|
+
await transaction.execute("DROP TABLE IF EXISTS collections");
|
|
219
|
+
await createTables(transaction);
|
|
220
|
+
await transaction.execute(`PRAGMA user_version = ${schemaVersion}`);
|
|
170
221
|
});
|
|
171
222
|
else await createTables(database);
|
|
172
223
|
return database;
|
|
@@ -648,7 +699,7 @@ function enqueueMutation(action) {
|
|
|
648
699
|
const database = await initializedDatabase();
|
|
649
700
|
const changes = /* @__PURE__ */ new Map();
|
|
650
701
|
try {
|
|
651
|
-
const value = await database.transaction(() => action(
|
|
702
|
+
const value = await database.transaction((transaction) => action(transaction, changes));
|
|
652
703
|
publishChanges(changes);
|
|
653
704
|
resolve(value);
|
|
654
705
|
} catch (error) {
|
|
@@ -4,6 +4,7 @@ import { l as schema } from "./schema-B7ELMpuI.js";
|
|
|
4
4
|
import { useAtom, useAtomValue, useSetAtom } from "jotai/react";
|
|
5
5
|
import { atom, getDefaultStore } from "jotai/vanilla";
|
|
6
6
|
import { atomFamily } from "jotai-family";
|
|
7
|
+
import { openDatabaseAsync } from "expo-sqlite";
|
|
7
8
|
|
|
8
9
|
//#region src/state/atom.ts
|
|
9
10
|
const storedAtomsKey = Symbol.for("bleam.state.storedAtoms.v1");
|
|
@@ -124,6 +125,55 @@ function internalJotaiWritableAtom(value) {
|
|
|
124
125
|
}
|
|
125
126
|
const internalStore = getDefaultStore();
|
|
126
127
|
|
|
128
|
+
//#endregion
|
|
129
|
+
//#region src/native-sqlite.ts
|
|
130
|
+
const databases = /* @__PURE__ */ new Map();
|
|
131
|
+
function toExpoParameters(parameters) {
|
|
132
|
+
return parameters;
|
|
133
|
+
}
|
|
134
|
+
function toSQLiteValue(value) {
|
|
135
|
+
if (typeof value === "string" || typeof value === "number" || value === null) return value;
|
|
136
|
+
throw new Error("SQLite blobs are not supported by Bleam state yet");
|
|
137
|
+
}
|
|
138
|
+
function toSQLiteRow(row) {
|
|
139
|
+
const output = {};
|
|
140
|
+
for (const [key, value] of Object.entries(row)) output[key] = toSQLiteValue(value);
|
|
141
|
+
return output;
|
|
142
|
+
}
|
|
143
|
+
var NativeSQLiteDatabase = class NativeSQLiteDatabase {
|
|
144
|
+
constructor(database) {
|
|
145
|
+
this.database = database;
|
|
146
|
+
}
|
|
147
|
+
async execute(query, parameters) {
|
|
148
|
+
await this.database.runAsync(query, toExpoParameters(parameters) ?? []);
|
|
149
|
+
}
|
|
150
|
+
async select(query, parameters) {
|
|
151
|
+
return (await this.database.getAllAsync(query, toExpoParameters(parameters) ?? [])).map(toSQLiteRow);
|
|
152
|
+
}
|
|
153
|
+
async get(query, parameters) {
|
|
154
|
+
const row = await this.database.getFirstAsync(query, toExpoParameters(parameters) ?? []);
|
|
155
|
+
return row ? toSQLiteRow(row) : void 0;
|
|
156
|
+
}
|
|
157
|
+
async transaction(action) {
|
|
158
|
+
let result;
|
|
159
|
+
await this.database.withExclusiveTransactionAsync(async (transaction) => {
|
|
160
|
+
result = await action(new NativeSQLiteDatabase(transaction));
|
|
161
|
+
});
|
|
162
|
+
return result;
|
|
163
|
+
}
|
|
164
|
+
close() {
|
|
165
|
+
return this.database.closeAsync();
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
function openNativeSQLiteDatabase(name = "bleam.sqlite3") {
|
|
169
|
+
let database = databases.get(name);
|
|
170
|
+
if (!database) {
|
|
171
|
+
database = openDatabaseAsync(name).then((value) => new NativeSQLiteDatabase(value));
|
|
172
|
+
databases.set(name, database);
|
|
173
|
+
}
|
|
174
|
+
return database;
|
|
175
|
+
}
|
|
176
|
+
|
|
127
177
|
//#endregion
|
|
128
178
|
//#region src/state/collection.ts
|
|
129
179
|
var CollectionVersionConflictError = class extends Error {
|
|
@@ -151,18 +201,18 @@ let jsonSqlSupportPromise;
|
|
|
151
201
|
let mutationPipeline = Promise.resolve();
|
|
152
202
|
let transactionCallbackStarting = false;
|
|
153
203
|
function getDatabase() {
|
|
154
|
-
databasePromise ??=
|
|
204
|
+
databasePromise ??= Promise.resolve().then(() => openNativeSQLiteDatabase(`${currentAppStorageKey()}.sqlite3`));
|
|
155
205
|
return databasePromise;
|
|
156
206
|
}
|
|
157
207
|
async function initializedDatabase() {
|
|
158
208
|
initializedPromise ??= (async () => {
|
|
159
209
|
const database = await getDatabase();
|
|
160
210
|
await database.execute("PRAGMA journal_mode = WAL");
|
|
161
|
-
if (numberValue(await database.get("PRAGMA user_version"), "user_version", 0) !== schemaVersion) await database.transaction(async () => {
|
|
162
|
-
await
|
|
163
|
-
await
|
|
164
|
-
await createTables(
|
|
165
|
-
await
|
|
211
|
+
if (numberValue(await database.get("PRAGMA user_version"), "user_version", 0) !== schemaVersion) await database.transaction(async (transaction) => {
|
|
212
|
+
await transaction.execute("DROP TABLE IF EXISTS links");
|
|
213
|
+
await transaction.execute("DROP TABLE IF EXISTS collections");
|
|
214
|
+
await createTables(transaction);
|
|
215
|
+
await transaction.execute(`PRAGMA user_version = ${schemaVersion}`);
|
|
166
216
|
});
|
|
167
217
|
else await createTables(database);
|
|
168
218
|
return database;
|
|
@@ -644,7 +694,7 @@ function enqueueMutation(action) {
|
|
|
644
694
|
const database = await initializedDatabase();
|
|
645
695
|
const changes = /* @__PURE__ */ new Map();
|
|
646
696
|
try {
|
|
647
|
-
const value = await database.transaction(() => action(
|
|
697
|
+
const value = await database.transaction((transaction) => action(transaction, changes));
|
|
648
698
|
publishChanges(changes);
|
|
649
699
|
resolve(value);
|
|
650
700
|
} catch (error) {
|
package/dist/state.cjs
CHANGED
|
@@ -2,7 +2,7 @@ require('./native-runtime-CsXnXkQn.cjs');
|
|
|
2
2
|
require('./crypto-CT3VZ7lF.cjs');
|
|
3
3
|
require('./app-storage-D8W4n8ey.cjs');
|
|
4
4
|
const require_schema = require('./schema-B7SLUBLN.cjs');
|
|
5
|
-
const require_state = require('./state-
|
|
5
|
+
const require_state = require('./state-Bm9GiRnU.cjs');
|
|
6
6
|
|
|
7
7
|
exports.CollectionVersionConflictError = require_state.CollectionVersionConflictError;
|
|
8
8
|
exports.array = require_schema.array;
|
package/dist/state.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as array, C as SchemaOutput, E as SchemaShape, F as number, I as object, P as literal, R as string, _ as ObjectField, b as SchemaInput, c as FieldPath, j as boolean, k as ValueAtFieldPath, s as FieldOutput, w as SchemaPatch } from "./schema-
|
|
1
|
+
import { A as array, C as SchemaOutput, E as SchemaShape, F as number, I as object, P as literal, R as string, _ as ObjectField, b as SchemaInput, c as FieldPath, j as boolean, k as ValueAtFieldPath, s as FieldOutput, w as SchemaPatch } from "./schema-DsXZBnvc.js";
|
|
2
2
|
import "jotai/vanilla";
|
|
3
3
|
|
|
4
4
|
//#region src/state/atom.d.ts
|
package/dist/state.js
CHANGED
|
@@ -2,6 +2,6 @@ import "./native-runtime-C85Nuc4F.js";
|
|
|
2
2
|
import "./crypto-BB92-Upx.js";
|
|
3
3
|
import "./app-storage-Isi5Bo0R.js";
|
|
4
4
|
import { c as object, n as array, o as literal, r as boolean, s as number, u as string } from "./schema-B7ELMpuI.js";
|
|
5
|
-
import { a as transactionAtom, c as useRow, h as useSetAtom, i as queryAtom, l as atom, m as useAtomValue, n as atomCollection, o as useField, p as useAtom, r as mutateAtom, s as useList, t as CollectionVersionConflictError } from "./state-
|
|
5
|
+
import { a as transactionAtom, c as useRow, h as useSetAtom, i as queryAtom, l as atom, m as useAtomValue, n as atomCollection, o as useField, p as useAtom, r as mutateAtom, s as useList, t as CollectionVersionConflictError } from "./state-D8Firo9w.js";
|
|
6
6
|
|
|
7
7
|
export { CollectionVersionConflictError, array, atom, atomCollection, boolean, literal, mutateAtom, number, object, queryAtom, string, transactionAtom, useAtom, useAtomValue, useField, useList, useRow, useSetAtom };
|
package/dist/window.d.cts
CHANGED
package/dist/window.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as SymbolName } from "./elements-
|
|
2
|
-
import * as
|
|
1
|
+
import { n as SymbolName } from "./elements-DX_YUveu.js";
|
|
2
|
+
import * as react3 from "react";
|
|
3
3
|
import { ComponentType } from "react";
|
|
4
4
|
import { StyleProp, ViewStyle } from "react-native";
|
|
5
5
|
|
|
@@ -55,7 +55,7 @@ type SidebarNavigatorConfig<Routes extends SidebarScreenMap> = {
|
|
|
55
55
|
style?: StyleProp<ViewStyle>;
|
|
56
56
|
};
|
|
57
57
|
declare function createSidebarNavigator<const Routes extends SidebarScreenMap>(config: SidebarNavigatorConfig<Routes>): {
|
|
58
|
-
Navigator: () =>
|
|
58
|
+
Navigator: () => react3.JSX.Element;
|
|
59
59
|
useNavigation: () => SidebarNavigation<Routes>;
|
|
60
60
|
useRoute: () => SidebarRouteState<Routes>;
|
|
61
61
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bleam",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"packageManager": "yarn@
|
|
3
|
+
"version": "0.0.14",
|
|
4
|
+
"packageManager": "yarn@4.17.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist",
|
|
@@ -10,9 +10,7 @@
|
|
|
10
10
|
"tsconfig.json",
|
|
11
11
|
"tsconfig.base.json"
|
|
12
12
|
],
|
|
13
|
-
"bin":
|
|
14
|
-
"bleam": "dist/cli.js"
|
|
15
|
-
},
|
|
13
|
+
"bin": "dist/cli.js",
|
|
16
14
|
"scripts": {
|
|
17
15
|
"build": "tsdown",
|
|
18
16
|
"prepublishOnly": "tsdown",
|
|
@@ -30,11 +28,11 @@
|
|
|
30
28
|
"dependencies": {
|
|
31
29
|
"@biomejs/biome": "^2.2.0",
|
|
32
30
|
"@expo/metro": "56.0.0",
|
|
33
|
-
"@nativescript-community/sqlite": "^3.5.9",
|
|
34
31
|
"@nativescript/react-native": "9.0.0-preview.4",
|
|
35
32
|
"@types/react": "~19.2.17",
|
|
36
33
|
"expo": "57",
|
|
37
34
|
"expo-splash-screen": "57.0.2",
|
|
35
|
+
"expo-sqlite": "~57.0.1",
|
|
38
36
|
"jotai": "2.20.2",
|
|
39
37
|
"jotai-family": "1.0.2",
|
|
40
38
|
"react": "19.2.3",
|
|
@@ -1,139 +1,17 @@
|
|
|
1
|
-
import { Button } from 'bleam/elements'
|
|
2
|
-
import { atom, useAtom } from 'bleam/state'
|
|
3
1
|
import { sx } from 'bleam/styles'
|
|
4
|
-
import {
|
|
2
|
+
import { Window } from 'bleam/window'
|
|
5
3
|
import { Text, View } from 'react-native'
|
|
6
4
|
|
|
7
5
|
const appName = 'Bleam Basic'
|
|
8
|
-
const counter = atom(0)
|
|
9
6
|
|
|
10
7
|
export default function App() {
|
|
11
|
-
const [count, setCount] = useAtom(counter)
|
|
12
|
-
|
|
13
8
|
return (
|
|
14
|
-
<View style={sx('flex-1')}>
|
|
15
|
-
<Window title={appName}
|
|
16
|
-
<
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
<View style={sx('flex-1', 'items-center', 'justify-center', 'px-6')}>
|
|
21
|
-
<View style={sx('items-center', 'gap-8')}>
|
|
22
|
-
<View
|
|
23
|
-
style={sx('h-44', 'w-44', 'items-center', 'justify-center')}
|
|
24
|
-
>
|
|
25
|
-
<View
|
|
26
|
-
style={sx(
|
|
27
|
-
'absolute',
|
|
28
|
-
'top-0',
|
|
29
|
-
'h-24',
|
|
30
|
-
'w-32',
|
|
31
|
-
'rounded-2xl',
|
|
32
|
-
'border',
|
|
33
|
-
'border-tertiary-label',
|
|
34
|
-
'bg-system',
|
|
35
|
-
'items-center',
|
|
36
|
-
'justify-center',
|
|
37
|
-
'rotate-30',
|
|
38
|
-
)}
|
|
39
|
-
>
|
|
40
|
-
<Text
|
|
41
|
-
style={sx(
|
|
42
|
-
'text-3xl',
|
|
43
|
-
'font-semibold',
|
|
44
|
-
'text-system-cyan',
|
|
45
|
-
'-rotate-30',
|
|
46
|
-
)}
|
|
47
|
-
>
|
|
48
|
-
B
|
|
49
|
-
</Text>
|
|
50
|
-
</View>
|
|
51
|
-
|
|
52
|
-
<View
|
|
53
|
-
style={sx(
|
|
54
|
-
'absolute',
|
|
55
|
-
'bottom-2',
|
|
56
|
-
'h-24',
|
|
57
|
-
'w-32',
|
|
58
|
-
'rounded-2xl',
|
|
59
|
-
'border-2',
|
|
60
|
-
'border-system-purple',
|
|
61
|
-
'bg-secondary-system',
|
|
62
|
-
'items-center',
|
|
63
|
-
'justify-center',
|
|
64
|
-
'rotate-30',
|
|
65
|
-
)}
|
|
66
|
-
>
|
|
67
|
-
<Text
|
|
68
|
-
style={sx(
|
|
69
|
-
'text-3xl',
|
|
70
|
-
'font-bold',
|
|
71
|
-
'text-system-purple',
|
|
72
|
-
'-rotate-30',
|
|
73
|
-
)}
|
|
74
|
-
>
|
|
75
|
-
JS
|
|
76
|
-
</Text>
|
|
77
|
-
</View>
|
|
78
|
-
</View>
|
|
79
|
-
|
|
80
|
-
<View style={sx('items-center')}>
|
|
81
|
-
<Text
|
|
82
|
-
style={sx(
|
|
83
|
-
'text-5xl',
|
|
84
|
-
'font-semibold',
|
|
85
|
-
'tracking-tighter',
|
|
86
|
-
'text-label',
|
|
87
|
-
'text-center',
|
|
88
|
-
)}
|
|
89
|
-
>
|
|
90
|
-
Get started
|
|
91
|
-
</Text>
|
|
92
|
-
<Text
|
|
93
|
-
style={sx(
|
|
94
|
-
'mt-6',
|
|
95
|
-
'text-lg',
|
|
96
|
-
'text-secondary-label',
|
|
97
|
-
'text-center',
|
|
98
|
-
)}
|
|
99
|
-
>
|
|
100
|
-
Edit{' '}
|
|
101
|
-
<Text
|
|
102
|
-
style={sx(
|
|
103
|
-
'rounded-md',
|
|
104
|
-
'italic',
|
|
105
|
-
'px-2',
|
|
106
|
-
'py-1',
|
|
107
|
-
'text-label',
|
|
108
|
-
)}
|
|
109
|
-
>
|
|
110
|
-
app/index.tsx
|
|
111
|
-
</Text>{' '}
|
|
112
|
-
and save to test{' '}
|
|
113
|
-
<Text
|
|
114
|
-
style={sx(
|
|
115
|
-
'rounded-md',
|
|
116
|
-
'italic',
|
|
117
|
-
'px-2',
|
|
118
|
-
'py-1',
|
|
119
|
-
'text-label',
|
|
120
|
-
)}
|
|
121
|
-
>
|
|
122
|
-
live reload
|
|
123
|
-
</Text>
|
|
124
|
-
</Text>
|
|
125
|
-
</View>
|
|
126
|
-
|
|
127
|
-
<Button
|
|
128
|
-
label={`Count is ${count}`}
|
|
129
|
-
variant="secondary"
|
|
130
|
-
size="regular"
|
|
131
|
-
onPress={() => setCount((value) => value + 1)}
|
|
132
|
-
/>
|
|
133
|
-
</View>
|
|
134
|
-
</View>
|
|
135
|
-
</View>
|
|
136
|
-
</View>
|
|
9
|
+
<View style={sx('flex-1', 'items-center', 'justify-center', 'px-6')}>
|
|
10
|
+
<Window title={appName} />
|
|
11
|
+
<Text style={sx('text-3xl', 'font-bold', 'text-label')}>{appName}</Text>
|
|
12
|
+
<Text style={sx('mt-2', 'text-base', 'text-secondary-label')}>
|
|
13
|
+
Open app/index.tsx to start working on your app.
|
|
14
|
+
</Text>
|
|
137
15
|
</View>
|
|
138
16
|
)
|
|
139
17
|
}
|
|
@@ -1,13 +1,47 @@
|
|
|
1
1
|
import { chat, useChat, useChatList } from 'bleam/ai'
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Button,
|
|
4
|
+
Conversation,
|
|
5
|
+
ConversationContent,
|
|
6
|
+
ConversationEmptyState,
|
|
7
|
+
ConversationScrollButton,
|
|
8
|
+
Message,
|
|
9
|
+
MessageActions,
|
|
10
|
+
MessageContent,
|
|
11
|
+
MessageStatus,
|
|
12
|
+
MessageText,
|
|
13
|
+
PromptInput,
|
|
14
|
+
PromptInputFooter,
|
|
15
|
+
PromptInputSubmit,
|
|
16
|
+
PromptInputTextarea,
|
|
17
|
+
} from 'bleam/elements'
|
|
3
18
|
import { sx } from 'bleam/styles'
|
|
4
19
|
import { Window } from 'bleam/window'
|
|
5
|
-
import { useEffect, useRef, useState } from 'react'
|
|
6
|
-
import { Text,
|
|
20
|
+
import { Suspense, useEffect, useRef, useState } from 'react'
|
|
21
|
+
import { Text, View } from 'react-native'
|
|
7
22
|
|
|
8
23
|
const appName = 'Bleam Basic'
|
|
9
24
|
|
|
10
25
|
export default function App() {
|
|
26
|
+
return (
|
|
27
|
+
<View style={sx('flex-1', 'p-8', 'gap-6')}>
|
|
28
|
+
<Window title={appName} />
|
|
29
|
+
<Text style={sx('text-3xl', 'font-semibold')}>Foundation Models</Text>
|
|
30
|
+
<Text style={sx('text-secondary-label')}>
|
|
31
|
+
Chats persist on this Mac and use Apple Foundation Models by default.
|
|
32
|
+
</Text>
|
|
33
|
+
<Suspense
|
|
34
|
+
fallback={
|
|
35
|
+
<Text style={sx('text-secondary-label')}>Loading local chats...</Text>
|
|
36
|
+
}
|
|
37
|
+
>
|
|
38
|
+
<ChatSession />
|
|
39
|
+
</Suspense>
|
|
40
|
+
</View>
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function ChatSession() {
|
|
11
45
|
const chats = useChatList()
|
|
12
46
|
const creating = useRef(false)
|
|
13
47
|
const [error, setError] = useState('')
|
|
@@ -25,15 +59,10 @@ export default function App() {
|
|
|
25
59
|
}, [chats.length])
|
|
26
60
|
|
|
27
61
|
return (
|
|
28
|
-
<View style={sx('flex-1'
|
|
29
|
-
<Window title={appName} />
|
|
30
|
-
<Text style={sx('text-3xl', 'font-semibold')}>Foundation Models</Text>
|
|
31
|
-
<Text style={sx('text-secondary-label')}>
|
|
32
|
-
Chats persist on this Mac and use Apple Foundation Models by default.
|
|
33
|
-
</Text>
|
|
62
|
+
<View style={sx('flex-1')}>
|
|
34
63
|
{error ? <Text style={sx('text-system-red')}>{error}</Text> : null}
|
|
35
64
|
{chats[0] ? (
|
|
36
|
-
<
|
|
65
|
+
<ChatConversation id={chats[0].id} />
|
|
37
66
|
) : (
|
|
38
67
|
<Text>Creating chat...</Text>
|
|
39
68
|
)}
|
|
@@ -41,7 +70,7 @@ export default function App() {
|
|
|
41
70
|
)
|
|
42
71
|
}
|
|
43
72
|
|
|
44
|
-
function
|
|
73
|
+
function ChatConversation({ id }: { id: string }) {
|
|
45
74
|
const conversation = useChat(id, {
|
|
46
75
|
system: 'You suggest practical, concise native Mac app ideas.',
|
|
47
76
|
})
|
|
@@ -56,39 +85,69 @@ function Conversation({ id }: { id: string }) {
|
|
|
56
85
|
: null
|
|
57
86
|
|
|
58
87
|
return (
|
|
59
|
-
<View style={sx('gap-4')}>
|
|
60
|
-
<
|
|
88
|
+
<View style={sx('flex-1', 'gap-4')}>
|
|
89
|
+
<Conversation>
|
|
90
|
+
<ConversationContent
|
|
91
|
+
data={conversation.messages}
|
|
92
|
+
keyExtractor={(message) => message.id}
|
|
93
|
+
ListEmptyComponent={
|
|
94
|
+
<ConversationEmptyState
|
|
95
|
+
title="Start a conversation"
|
|
96
|
+
description="Ask for a practical native Mac app idea."
|
|
97
|
+
/>
|
|
98
|
+
}
|
|
99
|
+
renderItem={({ item: message }) => (
|
|
100
|
+
<Message from={message.role}>
|
|
101
|
+
{message.content ? (
|
|
102
|
+
<MessageContent>
|
|
103
|
+
<MessageText>{message.content}</MessageText>
|
|
104
|
+
</MessageContent>
|
|
105
|
+
) : null}
|
|
106
|
+
{message.status !== 'completed' ? (
|
|
107
|
+
<MessageStatus status={message.status} />
|
|
108
|
+
) : null}
|
|
109
|
+
{retryable?.id === message.id ? (
|
|
110
|
+
<MessageActions>
|
|
111
|
+
<Button
|
|
112
|
+
label="Retry"
|
|
113
|
+
size="small"
|
|
114
|
+
variant="secondary"
|
|
115
|
+
onPress={() => void conversation.retry(message.id)}
|
|
116
|
+
/>
|
|
117
|
+
</MessageActions>
|
|
118
|
+
) : null}
|
|
119
|
+
</Message>
|
|
120
|
+
)}
|
|
121
|
+
/>
|
|
122
|
+
<ConversationScrollButton />
|
|
123
|
+
</Conversation>
|
|
124
|
+
|
|
125
|
+
<PromptInput
|
|
126
|
+
disabled={!conversation.canSend && !conversation.canCancel}
|
|
127
|
+
status={conversation.status}
|
|
61
128
|
value={prompt}
|
|
62
129
|
onChangeText={setPrompt}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
variant="secondary"
|
|
82
|
-
onPress={() => void conversation.retry(retryable.id)}
|
|
130
|
+
onSubmit={({ text }) => {
|
|
131
|
+
setPrompt('')
|
|
132
|
+
void conversation.send(text)
|
|
133
|
+
}}
|
|
134
|
+
>
|
|
135
|
+
<PromptInputTextarea />
|
|
136
|
+
<PromptInputFooter>
|
|
137
|
+
<View />
|
|
138
|
+
<PromptInputSubmit
|
|
139
|
+
disabled={!conversation.canCancel && !prompt.trim()}
|
|
140
|
+
onPress={({ text }) => {
|
|
141
|
+
if (conversation.canCancel) {
|
|
142
|
+
void conversation.cancel()
|
|
143
|
+
} else {
|
|
144
|
+
setPrompt('')
|
|
145
|
+
void conversation.send(text)
|
|
146
|
+
}
|
|
147
|
+
}}
|
|
83
148
|
/>
|
|
84
|
-
|
|
85
|
-
</
|
|
86
|
-
{conversation.messages.map((message) => (
|
|
87
|
-
<Text key={message.id} style={sx('text-lg', 'text-label')}>
|
|
88
|
-
{message.role === 'user' ? 'You: ' : 'Assistant: '}
|
|
89
|
-
{message.content || message.status}
|
|
90
|
-
</Text>
|
|
91
|
-
))}
|
|
149
|
+
</PromptInputFooter>
|
|
150
|
+
</PromptInput>
|
|
92
151
|
</View>
|
|
93
152
|
)
|
|
94
153
|
}
|
|
@@ -71,6 +71,8 @@ PODS:
|
|
|
71
71
|
- ExpoModulesWorklets (57.0.2):
|
|
72
72
|
- ExpoModulesCore
|
|
73
73
|
- ExpoModulesJSI
|
|
74
|
+
- ExpoSQLite (57.0.1):
|
|
75
|
+
- ExpoModulesCore
|
|
74
76
|
- FBLazyVector (0.86.0)
|
|
75
77
|
- hermes-engine (250829098.0.14):
|
|
76
78
|
- hermes-engine/Pre-built (= 250829098.0.14)
|
|
@@ -1932,6 +1934,7 @@ DEPENDENCIES:
|
|
|
1932
1934
|
- ExpoModulesCore (from `../node_modules/expo-modules-core`)
|
|
1933
1935
|
- ExpoModulesJSI (from `../node_modules/expo-modules-jsi/apple`)
|
|
1934
1936
|
- ExpoModulesWorklets (from `../node_modules/expo-modules-core`)
|
|
1937
|
+
- ExpoSQLite (from `../node_modules/expo-sqlite/ios`)
|
|
1935
1938
|
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
|
|
1936
1939
|
- hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`)
|
|
1937
1940
|
- "NativeScriptNativeApi (from `../node_modules/@nativescript/react-native`)"
|
|
@@ -2035,6 +2038,8 @@ EXTERNAL SOURCES:
|
|
|
2035
2038
|
:path: "../node_modules/expo-modules-jsi/apple"
|
|
2036
2039
|
ExpoModulesWorklets:
|
|
2037
2040
|
:path: "../node_modules/expo-modules-core"
|
|
2041
|
+
ExpoSQLite:
|
|
2042
|
+
:path: "../node_modules/expo-sqlite/ios"
|
|
2038
2043
|
FBLazyVector:
|
|
2039
2044
|
:path: "../node_modules/react-native/Libraries/FBLazyVector"
|
|
2040
2045
|
hermes-engine:
|
|
@@ -2202,6 +2207,7 @@ SPEC CHECKSUMS:
|
|
|
2202
2207
|
ExpoModulesCore: 747a01dfe7af61ad2e869f80bf983af1caa63378
|
|
2203
2208
|
ExpoModulesJSI: ef7f197a8e7eeb245557f560ade794bfc1abdc79
|
|
2204
2209
|
ExpoModulesWorklets: 0340ed9a30017f8597b90a1ef9aa210c43e44c4b
|
|
2210
|
+
ExpoSQLite: ddd65ed74bdebcff20f6766e682f9321ecb28ab8
|
|
2205
2211
|
FBLazyVector: b3e7ad108f0d882e30445c5527d774e3fd432f3d
|
|
2206
2212
|
hermes-engine: 6f298675a7f5d45e1a61a3c664a2b9618befb1e1
|
|
2207
2213
|
NativeScriptNativeApi: b35cf5bb2727adf20eb13d2b1bd8651d0698a362
|