bleam 0.0.8 → 0.0.9

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.
Files changed (87) hide show
  1. package/dist/cli.cjs +23 -4
  2. package/dist/cli.d.cts +2 -0
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.js +23 -4
  5. package/dist/{ui-Ce-pnUUA.d.ts → ui-Bg11tvlc.d.ts} +7 -7
  6. package/dist/ui.d.ts +1 -1
  7. package/dist/window.d.ts +1 -1
  8. package/package.json +4 -1
  9. package/templates/image-generation/app/index.tsx +1 -1
  10. package/templates/native/.gitattributes +1 -0
  11. package/templates/native/App.tsx +26 -0
  12. package/templates/native/app.json +12 -0
  13. package/templates/native/index.ts +8 -0
  14. package/templates/native/ios/.xcode.env +11 -0
  15. package/templates/native/ios/Bleam/AI/Flux2/Configuration/Flux2Config.swift +288 -0
  16. package/templates/native/ios/Bleam/AI/Flux2/Configuration/MemoryConfig.swift +233 -0
  17. package/templates/native/ios/Bleam/AI/Flux2/Configuration/MemoryOptimizationConfig.swift +157 -0
  18. package/templates/native/ios/Bleam/AI/Flux2/Configuration/ModelRegistry.swift +425 -0
  19. package/templates/native/ios/Bleam/AI/Flux2/Configuration/QuantizationConfig.swift +138 -0
  20. package/templates/native/ios/Bleam/AI/Flux2/Configuration/TransformerRepoProfile.swift +59 -0
  21. package/templates/native/ios/Bleam/AI/Flux2/Configuration/VAEConfig.swift +134 -0
  22. package/templates/native/ios/Bleam/AI/Flux2/Flux2Core.swift +55 -0
  23. package/templates/native/ios/Bleam/AI/Flux2/Loading/WeightLoader.swift +1192 -0
  24. package/templates/native/ios/Bleam/AI/Flux2/Pipeline/FluxImageRunner.swift +1282 -0
  25. package/templates/native/ios/Bleam/AI/Flux2/Pipeline/LatentUtils.swift +191 -0
  26. package/templates/native/ios/Bleam/AI/Flux2/Scheduler/FlowMatchEulerScheduler.swift +279 -0
  27. package/templates/native/ios/Bleam/AI/Flux2/Text/KleinTextEncoder.swift +380 -0
  28. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2Attention.swift +379 -0
  29. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2Embeddings.swift +159 -0
  30. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2FeedForward.swift +154 -0
  31. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2FusedKernels.swift +198 -0
  32. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2KVCache.swift +36 -0
  33. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2Modulation.swift +193 -0
  34. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2ParallelAttention.swift +389 -0
  35. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2RoPE.swift +304 -0
  36. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2SingleBlock.swift +290 -0
  37. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2Transformer.swift +530 -0
  38. package/templates/native/ios/Bleam/AI/Flux2/Transformer/Flux2TransformerBlock.swift +362 -0
  39. package/templates/native/ios/Bleam/AI/Flux2/Utils/Flux2Debug.swift +101 -0
  40. package/templates/native/ios/Bleam/AI/Flux2/Utils/MLXCheckpoint.swift +118 -0
  41. package/templates/native/ios/Bleam/AI/Flux2/Utils/MemoryManager.swift +201 -0
  42. package/templates/native/ios/Bleam/AI/Flux2/VAE/AutoencoderKL.swift +476 -0
  43. package/templates/native/ios/Bleam/AI/Flux2/VAE/ResnetBlock.swift +316 -0
  44. package/templates/native/ios/Bleam/AI/Flux2/VAE/VAEDecoder.swift +120 -0
  45. package/templates/native/ios/Bleam/AI/Flux2/VAE/VAEEncoder.swift +136 -0
  46. package/templates/native/ios/Bleam/AppDelegate.swift +373 -0
  47. package/templates/native/ios/Bleam/Appearance.swift +62 -0
  48. package/templates/native/ios/Bleam/Bridging-Header.h +3 -0
  49. package/templates/native/ios/Bleam/Images.xcassets/AppIcon.appiconset/Contents.json +13 -0
  50. package/templates/native/ios/Bleam/Images.xcassets/Contents.json +6 -0
  51. package/templates/native/ios/Bleam/Info.plist +76 -0
  52. package/templates/native/ios/Bleam/PrivacyInfo.xcprivacy +48 -0
  53. package/templates/native/ios/Bleam/SceneDelegate.swift +58 -0
  54. package/templates/native/ios/Bleam/SplashScreen.storyboard +47 -0
  55. package/templates/native/ios/Bleam/Supporting/Expo.plist +6 -0
  56. package/templates/native/ios/Bleam/bleam.entitlements +10 -0
  57. package/templates/native/ios/Bleam.xcodeproj/project.pbxproj +1146 -0
  58. package/templates/native/ios/Bleam.xcodeproj/xcshareddata/xcschemes/Bleam.xcscheme +88 -0
  59. package/templates/native/ios/GenerationService/GenerationService.entitlements +10 -0
  60. package/templates/native/ios/GenerationService/ImageGenerationRunner.swift +591 -0
  61. package/templates/native/ios/GenerationService/Info.plist +31 -0
  62. package/templates/native/ios/GenerationService/main.swift +165 -0
  63. package/templates/native/ios/PlatformHelper/Info.plist +29 -0
  64. package/templates/native/ios/PlatformHelper/main.swift +335 -0
  65. package/templates/native/ios/Podfile +198 -0
  66. package/templates/native/ios/Podfile.lock +2284 -0
  67. package/templates/native/ios/Podfile.properties.json +5 -0
  68. package/templates/native/ios/Shared/Generation/GenerationServiceProtocol.swift +12 -0
  69. package/templates/native/ios/Shared/Generation/GenerationWorkerProtocol.swift +124 -0
  70. package/templates/native/metro.config.js +6 -0
  71. package/templates/native/modules/bleam-runtime/BleamRuntime.podspec +14 -0
  72. package/templates/native/modules/bleam-runtime/expo-module.config.json +8 -0
  73. package/templates/native/modules/bleam-runtime/ios/AIModule.swift +1258 -0
  74. package/templates/native/modules/bleam-runtime/ios/GenerationContracts.swift +135 -0
  75. package/templates/native/modules/bleam-runtime/ios/PlatformModule.swift +313 -0
  76. package/templates/native/modules/bleam-runtime/package.json +5 -0
  77. package/templates/native/package.json +39 -0
  78. package/templates/native/scripts/build/mlx-frameworks.ts +421 -0
  79. package/templates/native/scripts/start/index.ts +474 -0
  80. package/templates/native/scripts/start/known-failures.ts +20 -0
  81. package/templates/native/scripts/start/loader.ts +76 -0
  82. package/templates/native/scripts/start/native-state.ts +242 -0
  83. package/templates/native/scripts/start/package.json +4 -0
  84. package/templates/native/scripts/start/swift-packages.ts +414 -0
  85. package/templates/native/scripts/start/xcode-formatter.ts +106 -0
  86. package/templates/native/tsconfig.json +14 -0
  87. package/templates/native/yarn.lock +3749 -0
package/dist/cli.cjs CHANGED
@@ -635,8 +635,9 @@ function writeProjectRuntimeConfig(projectRoot, config, origin) {
635
635
  }, null, 2)}\n`);
636
636
  return projectConfigPath;
637
637
  }
638
- function nativeRuntimeTemplateRoot() {
639
- return node_path.default.resolve(packageRoot, "..", "..", "app", "bleam");
638
+ function nativeRuntimeTemplateRoot(root = packageRoot) {
639
+ const bundledTemplate = node_path.default.join(root, "templates", "native");
640
+ return (0, node_fs.existsSync)(bundledTemplate) ? bundledTemplate : node_path.default.resolve(root, "..", "..", "app", "bleam");
640
641
  }
641
642
  function safeArtifactName(name) {
642
643
  return name.trim().replace(/[/:\\]/g, "-").replace(/\s+/g, " ") || "App";
@@ -742,8 +743,10 @@ function createBuildNativeWorkspace(options, config) {
742
743
  recursive: true,
743
744
  verbatimSymlinks: true,
744
745
  filter(source) {
745
- return !node_path.default.relative(templateRoot, source).split(node_path.default.sep).some((part) => {
746
- return part === "build" || part === "dist" || part === "node_modules" || part === ".expo" || part === "Pods" || part === ".xcode.env.local" || part === ".DS_Store" || part.endsWith(".xcworkspace");
746
+ const parts = node_path.default.relative(templateRoot, source).split(node_path.default.sep);
747
+ return !parts.some((part, index) => {
748
+ const frameworkBuildScript = part === "build" && index === 1 && parts[0] === "scripts";
749
+ return part === "build" && !frameworkBuildScript || part === "dist" || part === "node_modules" || part === ".expo" || part === "Pods" || part === ".xcode.env.local" || part === ".DS_Store" || part.endsWith(".xcworkspace");
747
750
  });
748
751
  }
749
752
  });
@@ -790,6 +793,20 @@ function installPods(nativeRoot) {
790
793
  runInheritedCommand("pod", ["install"], iosRoot);
791
794
  (0, node_fs.writeFileSync)(podInstallStampPath(iosRoot), `${expectedStamp}\n`);
792
795
  }
796
+ function ensureNativeFrameworks(nativeRoot) {
797
+ const frameworksRoot = node_path.default.join(nativeRoot, "ios", "Vendor", "MLXSwift", "0.31.6-macos");
798
+ if ([
799
+ "Cmlx",
800
+ "MLX",
801
+ "MLXNN",
802
+ "MLXOptimizers"
803
+ ].every((name) => (0, node_fs.existsSync)(node_path.default.join(frameworksRoot, `${name}.framework`)))) {
804
+ console.log("Using cached native MLX frameworks");
805
+ return;
806
+ }
807
+ console.log("Preparing native MLX frameworks...");
808
+ runInheritedCommand(node_path.default.join(resolvedDependencyRoot(), ".bin", "tsx"), [node_path.default.join(nativeRoot, "scripts", "build", "mlx-frameworks.ts")], nativeRoot);
809
+ }
793
810
  function podInstallInputStamp(iosRoot) {
794
811
  const inputHash = (0, node_crypto.createHash)("sha256");
795
812
  for (const relative of [
@@ -866,6 +883,7 @@ async function buildNativeArchives(options) {
866
883
  const config = readProjectConfig(options);
867
884
  preflightBuild(options, config);
868
885
  const nativeRoot = createBuildNativeWorkspace(options, config);
886
+ ensureNativeFrameworks(nativeRoot);
869
887
  installPods(nativeRoot);
870
888
  const archivePath = archiveNativeApp({
871
889
  nativeRoot,
@@ -1883,6 +1901,7 @@ const __test = {
1883
1901
  hasCurrentPodInstall,
1884
1902
  installedAppPath,
1885
1903
  installArchivedApp,
1904
+ nativeRuntimeTemplateRoot,
1886
1905
  nativeArchiveArgs,
1887
1906
  parseBuildOptions,
1888
1907
  parseNewOptions,
package/dist/cli.d.cts CHANGED
@@ -36,6 +36,7 @@ declare function createProject(options: {
36
36
  projectRoot: string;
37
37
  template?: ProjectTemplate;
38
38
  }): void;
39
+ declare function nativeRuntimeTemplateRoot(root?: string): string;
39
40
  declare function replaceOrInsertPlistString(plist: string, key: string, value: string): string;
40
41
  declare function createBuildNativeWorkspace(options: BuildOptions, config: ProjectConfig): string;
41
42
  declare function podInstallInputStamp(iosRoot: string): string;
@@ -77,6 +78,7 @@ declare const __test: {
77
78
  hasCurrentPodInstall: typeof hasCurrentPodInstall;
78
79
  installedAppPath: typeof installedAppPath;
79
80
  installArchivedApp: typeof installArchivedApp;
81
+ nativeRuntimeTemplateRoot: typeof nativeRuntimeTemplateRoot;
80
82
  nativeArchiveArgs: typeof nativeArchiveArgs;
81
83
  parseBuildOptions: typeof parseBuildOptions;
82
84
  parseNewOptions: typeof parseNewOptions;
package/dist/cli.d.ts CHANGED
@@ -36,6 +36,7 @@ declare function createProject(options: {
36
36
  projectRoot: string;
37
37
  template?: ProjectTemplate;
38
38
  }): void;
39
+ declare function nativeRuntimeTemplateRoot(root?: string): string;
39
40
  declare function replaceOrInsertPlistString(plist: string, key: string, value: string): string;
40
41
  declare function createBuildNativeWorkspace(options: BuildOptions, config: ProjectConfig): string;
41
42
  declare function podInstallInputStamp(iosRoot: string): string;
@@ -77,6 +78,7 @@ declare const __test: {
77
78
  hasCurrentPodInstall: typeof hasCurrentPodInstall;
78
79
  installedAppPath: typeof installedAppPath;
79
80
  installArchivedApp: typeof installArchivedApp;
81
+ nativeRuntimeTemplateRoot: typeof nativeRuntimeTemplateRoot;
80
82
  nativeArchiveArgs: typeof nativeArchiveArgs;
81
83
  parseBuildOptions: typeof parseBuildOptions;
82
84
  parseNewOptions: typeof parseNewOptions;
package/dist/cli.js CHANGED
@@ -623,8 +623,9 @@ function writeProjectRuntimeConfig(projectRoot, config, origin) {
623
623
  }, null, 2)}\n`);
624
624
  return projectConfigPath;
625
625
  }
626
- function nativeRuntimeTemplateRoot() {
627
- return path.resolve(packageRoot, "..", "..", "app", "bleam");
626
+ function nativeRuntimeTemplateRoot(root = packageRoot) {
627
+ const bundledTemplate = path.join(root, "templates", "native");
628
+ return existsSync(bundledTemplate) ? bundledTemplate : path.resolve(root, "..", "..", "app", "bleam");
628
629
  }
629
630
  function safeArtifactName(name) {
630
631
  return name.trim().replace(/[/:\\]/g, "-").replace(/\s+/g, " ") || "App";
@@ -730,8 +731,10 @@ function createBuildNativeWorkspace(options, config) {
730
731
  recursive: true,
731
732
  verbatimSymlinks: true,
732
733
  filter(source) {
733
- return !path.relative(templateRoot, source).split(path.sep).some((part) => {
734
- return part === "build" || part === "dist" || part === "node_modules" || part === ".expo" || part === "Pods" || part === ".xcode.env.local" || part === ".DS_Store" || part.endsWith(".xcworkspace");
734
+ const parts = path.relative(templateRoot, source).split(path.sep);
735
+ return !parts.some((part, index) => {
736
+ const frameworkBuildScript = part === "build" && index === 1 && parts[0] === "scripts";
737
+ return part === "build" && !frameworkBuildScript || part === "dist" || part === "node_modules" || part === ".expo" || part === "Pods" || part === ".xcode.env.local" || part === ".DS_Store" || part.endsWith(".xcworkspace");
735
738
  });
736
739
  }
737
740
  });
@@ -778,6 +781,20 @@ function installPods(nativeRoot) {
778
781
  runInheritedCommand("pod", ["install"], iosRoot);
779
782
  writeFileSync(podInstallStampPath(iosRoot), `${expectedStamp}\n`);
780
783
  }
784
+ function ensureNativeFrameworks(nativeRoot) {
785
+ const frameworksRoot = path.join(nativeRoot, "ios", "Vendor", "MLXSwift", "0.31.6-macos");
786
+ if ([
787
+ "Cmlx",
788
+ "MLX",
789
+ "MLXNN",
790
+ "MLXOptimizers"
791
+ ].every((name) => existsSync(path.join(frameworksRoot, `${name}.framework`)))) {
792
+ console.log("Using cached native MLX frameworks");
793
+ return;
794
+ }
795
+ console.log("Preparing native MLX frameworks...");
796
+ runInheritedCommand(path.join(resolvedDependencyRoot(), ".bin", "tsx"), [path.join(nativeRoot, "scripts", "build", "mlx-frameworks.ts")], nativeRoot);
797
+ }
781
798
  function podInstallInputStamp(iosRoot) {
782
799
  const inputHash = createHash("sha256");
783
800
  for (const relative of [
@@ -854,6 +871,7 @@ async function buildNativeArchives(options) {
854
871
  const config = readProjectConfig(options);
855
872
  preflightBuild(options, config);
856
873
  const nativeRoot = createBuildNativeWorkspace(options, config);
874
+ ensureNativeFrameworks(nativeRoot);
857
875
  installPods(nativeRoot);
858
876
  const archivePath = archiveNativeApp({
859
877
  nativeRoot,
@@ -1871,6 +1889,7 @@ const __test = {
1871
1889
  hasCurrentPodInstall,
1872
1890
  installedAppPath,
1873
1891
  installArchivedApp,
1892
+ nativeRuntimeTemplateRoot,
1874
1893
  nativeArchiveArgs,
1875
1894
  parseBuildOptions,
1876
1895
  parseNewOptions,
@@ -1,4 +1,4 @@
1
- import * as _nativescript_react_native33 from "@nativescript/react-native";
1
+ import * as _nativescript_react_native27 from "@nativescript/react-native";
2
2
  import { ReactNode } from "react";
3
3
  import { ColorValue, StyleProp, TextStyle, ViewStyle } from "react-native";
4
4
 
@@ -18,7 +18,7 @@ type ButtonProps = {
18
18
  onPress?: () => void;
19
19
  style?: StyleProp<NativeStyle>;
20
20
  };
21
- declare const Button: _nativescript_react_native33.UIKitViewComponent<ButtonProps, UIButton>;
21
+ declare const Button: _nativescript_react_native27.UIKitViewComponent<ButtonProps, UIButton>;
22
22
  //#endregion
23
23
  //#region src/ui/label.d.ts
24
24
  type LabelTone = 'primary' | 'secondary' | 'tertiary';
@@ -29,7 +29,7 @@ type LabelProps = {
29
29
  numberOfLines?: number;
30
30
  style?: StyleProp<NativeStyle>;
31
31
  };
32
- declare const Label: _nativescript_react_native33.UIKitViewComponent<LabelProps, UILabel>;
32
+ declare const Label: _nativescript_react_native27.UIKitViewComponent<LabelProps, UILabel>;
33
33
  //#endregion
34
34
  //#region src/ui/symbol.d.ts
35
35
  type SymbolName = string;
@@ -43,7 +43,7 @@ type SymbolProps = {
43
43
  color?: ColorValue;
44
44
  style?: StyleProp<NativeStyle>;
45
45
  };
46
- declare const Symbol: _nativescript_react_native33.UIKitViewComponent<SymbolProps, UIImageView>;
46
+ declare const Symbol: _nativescript_react_native27.UIKitViewComponent<SymbolProps, UIImageView>;
47
47
  //#endregion
48
48
  //#region src/ui/glass-shared.d.ts
49
49
  type GlassStyle = 'regular' | 'clear' | 'none';
@@ -73,10 +73,10 @@ type GlassContainerProps = {
73
73
  };
74
74
  //#endregion
75
75
  //#region src/ui/glass-view.d.ts
76
- declare const GlassView: _nativescript_react_native33.UIKitViewComponent<GlassViewProps, _nativescript_react_native33.UIKitContainerResult<UIVisualEffectView, UIView>>;
76
+ declare const GlassView: _nativescript_react_native27.UIKitViewComponent<GlassViewProps, _nativescript_react_native27.UIKitContainerResult<UIVisualEffectView, UIView>>;
77
77
  //#endregion
78
78
  //#region src/ui/glass-container.d.ts
79
- declare const GlassContainer: _nativescript_react_native33.UIKitViewComponent<GlassContainerProps, _nativescript_react_native33.UIKitContainerResult<UIVisualEffectView, UIView>>;
79
+ declare const GlassContainer: _nativescript_react_native27.UIKitViewComponent<GlassContainerProps, _nativescript_react_native27.UIKitContainerResult<UIVisualEffectView, UIView>>;
80
80
  //#endregion
81
81
  //#region src/ui/blur-view.d.ts
82
82
  type BlurIntensity = 'ultraThin' | 'thin' | 'regular' | 'thick' | 'chrome';
@@ -87,6 +87,6 @@ type BlurViewProps = {
87
87
  intensity?: BlurIntensity;
88
88
  colorScheme?: BlurColorScheme;
89
89
  };
90
- declare const BlurView: _nativescript_react_native33.UIKitViewComponent<BlurViewProps, _nativescript_react_native33.UIKitContainerResult<UIVisualEffectView, UIView>>;
90
+ declare const BlurView: _nativescript_react_native27.UIKitViewComponent<BlurViewProps, _nativescript_react_native27.UIKitContainerResult<UIVisualEffectView, UIView>>;
91
91
  //#endregion
92
92
  export { ButtonVariant as C, ButtonSize as S, Label as _, GlassContainer as a, Button as b, GlassEffectStyleConfig as c, GlassVisualStyle as d, Symbol as f, SymbolWeight as g, SymbolScale as h, BlurViewProps as i, GlassStyle as l, SymbolProps as m, BlurIntensity as n, GlassView as o, SymbolName as p, BlurView as r, GlassContainerProps as s, BlurColorScheme as t, GlassViewProps as u, LabelProps as v, ButtonProps as x, LabelTone as y };
package/dist/ui.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { C as ButtonVariant, S as ButtonSize, _ as Label, a as GlassContainer, b as Button, c as GlassEffectStyleConfig, d as GlassVisualStyle, f as Symbol, g as SymbolWeight, h as SymbolScale, i as BlurViewProps, l as GlassStyle, m as SymbolProps, n as BlurIntensity, o as GlassView, p as SymbolName, r as BlurView, s as GlassContainerProps, t as BlurColorScheme, u as GlassViewProps, v as LabelProps, x as ButtonProps, y as LabelTone } from "./ui-Ce-pnUUA.js";
1
+ import { C as ButtonVariant, S as ButtonSize, _ as Label, a as GlassContainer, b as Button, c as GlassEffectStyleConfig, d as GlassVisualStyle, f as Symbol, g as SymbolWeight, h as SymbolScale, i as BlurViewProps, l as GlassStyle, m as SymbolProps, n as BlurIntensity, o as GlassView, p as SymbolName, r as BlurView, s as GlassContainerProps, t as BlurColorScheme, u as GlassViewProps, v as LabelProps, x as ButtonProps, y as LabelTone } from "./ui-Bg11tvlc.js";
2
2
  export { BlurColorScheme, BlurIntensity, BlurView, BlurViewProps, Button, ButtonProps, ButtonSize, ButtonVariant, GlassContainer, GlassContainerProps, GlassEffectStyleConfig, GlassStyle, GlassView, GlassViewProps, GlassVisualStyle, Label, LabelProps, LabelTone, Symbol, SymbolName, SymbolProps, SymbolScale, SymbolWeight };
package/dist/window.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { p as SymbolName } from "./ui-Ce-pnUUA.js";
1
+ import { p as SymbolName } from "./ui-Bg11tvlc.js";
2
2
  import * as react3 from "react";
3
3
  import { ComponentType } from "react";
4
4
  import { StyleProp, ViewStyle } from "react-native";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bleam",
3
- "version": "0.0.8",
3
+ "version": "0.0.9",
4
4
  "packageManager": "yarn@1.22.22",
5
5
  "type": "module",
6
6
  "files": [
@@ -15,6 +15,9 @@
15
15
  },
16
16
  "scripts": {
17
17
  "build": "tsdown",
18
+ "prepublishOnly": "tsdown",
19
+ "prepack": "node scripts/prepare-native-template.mjs",
20
+ "postpack": "node scripts/clean-native-template.mjs",
18
21
  "test": "vitest run",
19
22
  "typecheck": "tsc --noEmit -p tsconfig.build.json"
20
23
  },
@@ -16,7 +16,7 @@ export default function App() {
16
16
  try {
17
17
  const result = await generateImage({
18
18
  prompt: 'A precise editorial illustration of a small native Mac app',
19
- aspectRatio: 'square',
19
+ aspectRatio: '1:1',
20
20
  })
21
21
  setUri(result.uri)
22
22
  setStatus(`Completed with seed ${result.metadata.seed}`)
@@ -0,0 +1 @@
1
+ *.pbxproj -text
@@ -0,0 +1,26 @@
1
+ import NativeScript from '@nativescript/react-native'
2
+ import { StyleSheet, Text, View } from 'react-native'
3
+
4
+ NativeScript.init()
5
+
6
+ export default function App() {
7
+ return (
8
+ <View style={styles.canvas}>
9
+ <Text style={styles.title}>Bleam</Text>
10
+ <Text style={styles.message}>
11
+ Run a Bleam project with npx bleam new or bleam dev.
12
+ </Text>
13
+ </View>
14
+ )
15
+ }
16
+
17
+ const styles = StyleSheet.create({
18
+ canvas: {
19
+ flex: 1,
20
+ alignItems: 'center',
21
+ justifyContent: 'center',
22
+ backgroundColor: '#0b0b0b',
23
+ },
24
+ title: { color: '#f5f5f5', fontSize: 28, fontWeight: '700' },
25
+ message: { color: '#888', fontSize: 14, marginTop: 10 },
26
+ })
@@ -0,0 +1,12 @@
1
+ {
2
+ "expo": {
3
+ "name": "Bleam",
4
+ "slug": "bleam",
5
+ "version": "1.0.0",
6
+ "platforms": ["ios"],
7
+ "ios": {
8
+ "appleTeamId": "5SZ3H5P69M",
9
+ "bundleIdentifier": "dev.bleam.app"
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,8 @@
1
+ import { registerRootComponent } from 'expo'
2
+
3
+ import App from './App'
4
+
5
+ // registerRootComponent calls AppRegistry.registerComponent('main', () => App);
6
+ // It also ensures that whether you load the app in Expo Go or in a native build,
7
+ // the environment is set up appropriately
8
+ registerRootComponent(App)
@@ -0,0 +1,11 @@
1
+ # This `.xcode.env` file is versioned and is used to source the environment
2
+ # used when running script phases inside Xcode.
3
+ # To customize your local environment, you can create an `.xcode.env.local`
4
+ # file that is not versioned.
5
+
6
+ # NODE_BINARY variable contains the PATH to the node executable.
7
+ #
8
+ # Customize the NODE_BINARY variable here.
9
+ # For example, to use nvm with brew, add the following line
10
+ # . "$(brew --prefix nvm)/nvm.sh" --no-use
11
+ export NODE_BINARY=$(command -v node)
@@ -0,0 +1,288 @@
1
+ // Flux2Config.swift - Flux.2 Transformer Configuration
2
+ // Copyright 2025 Vincent Gourbin
3
+
4
+ import Foundation
5
+
6
+ // MARK: - Model Selection
7
+
8
+ /// Flux.2 model variants
9
+ public enum Flux2Model: String, CaseIterable, Sendable {
10
+ /// Flux.2 Klein 4B - 4B parameters, Qwen3-4B text encoder (Apache 2.0)
11
+ case klein4B = "klein-4b"
12
+ /// Flux.2 Klein 9B - 9B parameters, Qwen3-8B text encoder (Apache 2.0)
13
+ case klein9B = "klein-9b"
14
+
15
+ public var displayName: String {
16
+ switch self {
17
+ case .klein4B: return "Flux.2 Klein 4B"
18
+ case .klein9B: return "Flux.2 Klein 9B"
19
+ }
20
+ }
21
+
22
+ /// Whether this is a base (non-distilled) model for training
23
+ public var isBaseModel: Bool {
24
+ false
25
+ }
26
+
27
+ /// Whether this model can be used for inference
28
+ public var isForInference: Bool {
29
+ true
30
+ }
31
+
32
+ /// Whether this model can be used for LoRA training
33
+ public var isForTraining: Bool {
34
+ false
35
+ }
36
+
37
+ /// Get the base (non-distilled) variant for training, if available
38
+ public var trainingVariant: Flux2Model {
39
+ .klein4B
40
+ }
41
+
42
+ /// Get the distilled variant for inference (validation images during training)
43
+ public var inferenceVariant: Flux2Model {
44
+ .klein4B
45
+ }
46
+
47
+ /// Whether this model uses guidance embeddings
48
+ public var usesGuidanceEmbeds: Bool {
49
+ false
50
+ }
51
+
52
+ /// Joint attention dimension (text encoder output)
53
+ public var jointAttentionDim: Int {
54
+ switch self {
55
+ case .klein4B: return 7680 // Qwen3-4B: 3 × 2560
56
+ case .klein9B: return 12288 // Qwen3-8B: 3 × 4096
57
+ }
58
+ }
59
+
60
+ /// Get the transformer configuration for this model
61
+ public var transformerConfig: Flux2TransformerConfig {
62
+ switch self {
63
+ case .klein4B: return .klein4B
64
+ case .klein9B: return .klein9B
65
+ }
66
+ }
67
+
68
+ /// Estimated VRAM usage in GB
69
+ public var estimatedVRAM: Int {
70
+ switch self {
71
+ case .klein4B: return 13
72
+ case .klein9B: return 20
73
+ }
74
+ }
75
+
76
+ /// License information
77
+ public var license: String {
78
+ "Apache 2.0"
79
+ }
80
+
81
+ /// Whether this model can be used commercially
82
+ public var isCommercialUseAllowed: Bool {
83
+ true
84
+ }
85
+
86
+ /// Recommended number of inference steps for optimal quality
87
+ public var defaultSteps: Int {
88
+ 4
89
+ }
90
+
91
+ /// Recommended guidance scale for optimal quality
92
+ public var defaultGuidance: Float {
93
+ 1.0
94
+ }
95
+
96
+ /// Estimated generation time in seconds (1024x1024 on M2 Max)
97
+ public var estimatedTimeSeconds: Int {
98
+ switch self {
99
+ case .klein4B: return 26
100
+ case .klein9B: return 45
101
+ }
102
+ }
103
+
104
+ /// Maximum number of reference images for I2I generation
105
+ /// Source: https://docs.bfl.ai/flux_2/flux2_image_editing
106
+ public var maxReferenceImages: Int {
107
+ 4
108
+ }
109
+ }
110
+
111
+ // MARK: - Transformer Configuration
112
+
113
+ /// Configuration for the Flux.2 diffusion transformer
114
+ public struct Flux2TransformerConfig: Codable, Sendable {
115
+ /// Patch size for input embedding (1 for Flux.2)
116
+ public var patchSize: Int
117
+
118
+ /// Number of input channels (128 for Flux.2 latents)
119
+ public var inChannels: Int
120
+
121
+ /// Number of output channels (same as input)
122
+ public var outChannels: Int
123
+
124
+ /// Number of double-stream transformer blocks
125
+ public var numLayers: Int
126
+
127
+ /// Number of single-stream transformer blocks
128
+ public var numSingleLayers: Int
129
+
130
+ /// Dimension of each attention head
131
+ public var attentionHeadDim: Int
132
+
133
+ /// Number of attention heads
134
+ public var numAttentionHeads: Int
135
+
136
+ /// Inner dimension for transformer (numAttentionHeads * attentionHeadDim)
137
+ public var innerDim: Int {
138
+ numAttentionHeads * attentionHeadDim
139
+ }
140
+
141
+ /// Dimension of joint attention (from Mistral embeddings: 15360)
142
+ public var jointAttentionDim: Int
143
+
144
+ /// Dimension of pooled projection (time + guidance embeddings)
145
+ public var pooledProjectionDim: Int
146
+
147
+ /// Whether to use guidance embedding
148
+ public var guidanceEmbeds: Bool
149
+
150
+ /// Axes dimensions for RoPE [T, H, W, L]
151
+ public var axesDimsRope: [Int]
152
+
153
+ /// Base theta for RoPE
154
+ public var ropeTheta: Float
155
+
156
+ /// MLP expansion ratio (3.0 for Flux.2, determines FFN hidden dimension)
157
+ public var mlpRatio: Float
158
+
159
+ /// Activation function for feedforward
160
+ public var activationFunction: String
161
+
162
+ public init(
163
+ patchSize: Int = 1,
164
+ inChannels: Int = 128,
165
+ outChannels: Int = 128,
166
+ numLayers: Int = 8,
167
+ numSingleLayers: Int = 48,
168
+ attentionHeadDim: Int = 128,
169
+ numAttentionHeads: Int = 48,
170
+ jointAttentionDim: Int = 15360,
171
+ pooledProjectionDim: Int = 768,
172
+ guidanceEmbeds: Bool = true,
173
+ axesDimsRope: [Int] = [32, 32, 32, 32],
174
+ ropeTheta: Float = 2000.0,
175
+ mlpRatio: Float = 3.0,
176
+ activationFunction: String = "silu"
177
+ ) {
178
+ self.patchSize = patchSize
179
+ self.inChannels = inChannels
180
+ self.outChannels = outChannels
181
+ self.numLayers = numLayers
182
+ self.numSingleLayers = numSingleLayers
183
+ self.attentionHeadDim = attentionHeadDim
184
+ self.numAttentionHeads = numAttentionHeads
185
+ self.jointAttentionDim = jointAttentionDim
186
+ self.pooledProjectionDim = pooledProjectionDim
187
+ self.guidanceEmbeds = guidanceEmbeds
188
+ self.axesDimsRope = axesDimsRope
189
+ self.ropeTheta = ropeTheta
190
+ self.mlpRatio = mlpRatio
191
+ self.activationFunction = activationFunction
192
+ }
193
+
194
+ /// Flux.2 Klein 4B configuration
195
+ /// 4B parameters, 5 double + 20 single blocks
196
+ public static let klein4B = Flux2TransformerConfig(
197
+ patchSize: 1,
198
+ inChannels: 128,
199
+ outChannels: 128,
200
+ numLayers: 5,
201
+ numSingleLayers: 20,
202
+ attentionHeadDim: 128,
203
+ numAttentionHeads: 24, // 24 × 128 = 3072
204
+ jointAttentionDim: 7680, // Qwen3-4B: 3 × 2560
205
+ pooledProjectionDim: 768,
206
+ guidanceEmbeds: false,
207
+ axesDimsRope: [32, 32, 32, 32],
208
+ ropeTheta: 2000.0,
209
+ mlpRatio: 3.0,
210
+ activationFunction: "silu"
211
+ )
212
+
213
+ /// Flux.2 Klein 9B configuration
214
+ /// 9B parameters, 8 double + 24 single blocks
215
+ public static let klein9B = Flux2TransformerConfig(
216
+ patchSize: 1,
217
+ inChannels: 128,
218
+ outChannels: 128,
219
+ numLayers: 8,
220
+ numSingleLayers: 24,
221
+ attentionHeadDim: 128,
222
+ numAttentionHeads: 32, // 32 × 128 = 4096
223
+ jointAttentionDim: 12288, // Qwen3-8B: 3 × 4096
224
+ pooledProjectionDim: 768,
225
+ guidanceEmbeds: false,
226
+ axesDimsRope: [32, 32, 32, 32],
227
+ ropeTheta: 2000.0,
228
+ mlpRatio: 3.0,
229
+ activationFunction: "silu"
230
+ )
231
+
232
+ // MARK: - Codable
233
+
234
+ enum CodingKeys: String, CodingKey {
235
+ case patchSize = "patch_size"
236
+ case inChannels = "in_channels"
237
+ case outChannels = "out_channels"
238
+ case numLayers = "num_layers"
239
+ case numSingleLayers = "num_single_layers"
240
+ case attentionHeadDim = "attention_head_dim"
241
+ case numAttentionHeads = "num_attention_heads"
242
+ case jointAttentionDim = "joint_attention_dim"
243
+ case pooledProjectionDim = "pooled_projection_dim"
244
+ case guidanceEmbeds = "guidance_embeds"
245
+ case axesDimsRope = "axes_dims_rope"
246
+ case ropeTheta = "rope_theta"
247
+ case mlpRatio = "mlp_ratio"
248
+ case activationFunction = "activation_function"
249
+ }
250
+
251
+ public init(from decoder: Decoder) throws {
252
+ let container = try decoder.container(keyedBy: CodingKeys.self)
253
+
254
+ patchSize = try container.decodeIfPresent(Int.self, forKey: .patchSize) ?? 1
255
+ inChannels = try container.decodeIfPresent(Int.self, forKey: .inChannels) ?? 128
256
+ outChannels = try container.decodeIfPresent(Int.self, forKey: .outChannels) ?? 128
257
+ numLayers = try container.decodeIfPresent(Int.self, forKey: .numLayers) ?? 8
258
+ numSingleLayers = try container.decodeIfPresent(Int.self, forKey: .numSingleLayers) ?? 48
259
+ attentionHeadDim = try container.decodeIfPresent(Int.self, forKey: .attentionHeadDim) ?? 128
260
+ numAttentionHeads = try container.decodeIfPresent(Int.self, forKey: .numAttentionHeads) ?? 48
261
+ jointAttentionDim = try container.decodeIfPresent(Int.self, forKey: .jointAttentionDim) ?? 15360
262
+ pooledProjectionDim = try container.decodeIfPresent(Int.self, forKey: .pooledProjectionDim) ?? 768
263
+ guidanceEmbeds = try container.decodeIfPresent(Bool.self, forKey: .guidanceEmbeds) ?? true
264
+ axesDimsRope = try container.decodeIfPresent([Int].self, forKey: .axesDimsRope) ?? [32, 32, 32, 32]
265
+ ropeTheta = try container.decodeIfPresent(Float.self, forKey: .ropeTheta) ?? 2000.0
266
+ mlpRatio = try container.decodeIfPresent(Float.self, forKey: .mlpRatio) ?? 3.0
267
+ activationFunction = try container.decodeIfPresent(String.self, forKey: .activationFunction) ?? "silu"
268
+ }
269
+
270
+ /// Load configuration from a JSON file
271
+ public static func load(from url: URL) throws -> Flux2TransformerConfig {
272
+ let data = try Data(contentsOf: url)
273
+ return try JSONDecoder().decode(Flux2TransformerConfig.self, from: data)
274
+ }
275
+ }
276
+
277
+ extension Flux2TransformerConfig: CustomStringConvertible {
278
+ public var description: String {
279
+ """
280
+ Flux2TransformerConfig(
281
+ layers: \(numLayers) double + \(numSingleLayers) single,
282
+ heads: \(numAttentionHeads) × \(attentionHeadDim) = \(innerDim),
283
+ jointDim: \(jointAttentionDim),
284
+ rope: \(axesDimsRope) θ=\(ropeTheta)
285
+ )
286
+ """
287
+ }
288
+ }