@@ -33,7 +33,7 @@ import * as fileStorage from './store/fileStorage.js';
3333import * as folderPersistence from './services/folderPersistence.js';
3434import workspaceService from './services/WorkspaceService.js';
3535import gitFederationService from './services/gitFederationService.js';
36- import { pickFolder, getFileInFolder, listFilesInFolder } from './utils/fileAccessAdapter.js';
36+ import { pickFolder, getFileInFolder, listFilesInFolder, writeFile } from './utils/fileAccessAdapter.js';
3737import AutoGraphModal from './components/AutoGraphModal';
3838import ForceSimulationModal from './components/ForceSimulationModal';
3939import { parseInputData, generateGraph } from './services/autoGraphGenerator';
@@ -13392,32 +13392,77 @@ function NodeCanvas() {
1339213392 onFolderSelected={async (folderPath, universeName) => {
1339313393 try {
1339413394 if (folderPath) {
13395- // 1. Link the folder using WorkspaceService
13395+ // 1. Link the folder using WorkspaceService (for config persistence)
1339613396 await workspaceService.linkFolder(folderPath);
1339713397
13398- // 2. Create Universe using gitFederationService so it appears in UniversesList
13398+ // 2. Create the .redstring file in the user's selected folder
1339913399 const safeName = (universeName && universeName.trim()) ? universeName.trim() : "Universe";
13400+ const filename = `${safeName}.redstring`;
13401+
13402+ // Create empty universe state
13403+ const emptyState = {
13404+ graph: { id: 'root', nodes: new Map(), edges: new Map() },
13405+ nodePrototypes: new Map(),
13406+ graphRegistry: new Map([['root', { id: 'root', nodes: new Map(), edges: new Map() }]]),
13407+ nodeDefinitionIndices: new Map()
13408+ };
13409+
13410+ // Create the file in the folder
13411+ const fileHandleResult = await getFileInFolder(folderPath, filename, true);
13412+ const fileHandle = fileHandleResult.handle || fileHandleResult;
13413+
13414+ // Write initial empty state to the file
13415+ await writeFile(fileHandle, JSON.stringify({
13416+ version: "1.0",
13417+ nodes: [],
13418+ edges: [],
13419+ graphs: [{ id: 'root', name: 'Root', nodes: [], edges: [] }],
13420+ prototypes: [],
13421+ metadata: { name: safeName, created: new Date().toISOString() }
13422+ }, null, 2));
13423+
13424+ console.log('[NodeCanvas] Created universe file:', filename);
1340013425
13401- // This registers the universe with universeBackendBridge
13426+ // 3. Create Universe in gitFederationService so it appears in UniversesList
1340213427 const result = await gitFederationService.createUniverse(safeName, {
1340313428 enableLocal: true,
1340413429 enableGit: false,
1340513430 sourceOfTruth: 'local'
1340613431 });
1340713432
13433+ const universeSlug = result?.createdUniverse?.slug || safeName.toLowerCase().replace(/\s+/g, '-');
1340813434 console.log('[NodeCanvas] Universe created via gitFederationService:', result);
1340913435
13410- // 3. Update store state
13436+ // 4. Register the file handle with universeBackend so it can save to the file
13437+ // Use the bridge's sendCommand to set the file handle
13438+ try {
13439+ const { default: universeBackend } = await import('./services/universeBackend.js');
13440+ await universeBackend.setFileHandle(universeSlug, fileHandle, {
13441+ displayPath: filename,
13442+ fileName: filename,
13443+ suppressNotification: true
13444+ });
13445+ console.log('[NodeCanvas] Registered file handle with universeBackend');
13446+ } catch (handleError) {
13447+ console.warn('[NodeCanvas] Could not register file handle:', handleError);
13448+ }
13449+
13450+ // 5. Update store state
1341113451 storeActions.setStorageMode('folder');
1341213452 storeActions.setUniverseConnected(true);
13413- storeActions.setUniverseLoaded(true, true); // Set hasUniverseFile=true to exit loading screen
13453+ storeActions.setUniverseLoaded(true, true);
13454+
13455+ // 6. Update WorkspaceService config
13456+ workspaceService.config.activeUniverse = filename;
13457+ workspaceService.config.lastOpened = Date.now();
13458+ await workspaceService.saveConfig();
1341413459
13415- // 4 . Mark onboarding as complete
13460+ // 7 . Mark onboarding as complete
1341613461 if (typeof window !== 'undefined') {
1341713462 localStorage.setItem(getStorageKey('redstring-alpha-welcome-seen'), 'true');
1341813463 }
1341913464
13420- // 5 . Close modal and open Panel
13465+ // 8 . Close modal and open Panel
1342113466 setShowStorageSetupModal(false);
1342213467 setLeftPanelExpanded(true);
1342313468
0 commit comments