Skip to content

feat(dartpad-preview): Introduce project session ids - #4006

Draft
dtetruash-nl wants to merge 5 commits into
dartpad-preview-remove-restore-offer-bannerfrom
dartpad-preview-introduce-project-persistence-session-ids
Draft

dtetruash-nl wants to merge 5 commits into
dartpad-preview-remove-restore-offer-bannerfrom
dartpad-preview-introduce-project-persistence-session-ids

Conversation

@dtetruash-nl

@dtetruash-nl dtetruash-nl commented Oct 9, 2026 •

Copy link
Copy Markdown
Collaborator

In preparation for updated project persistance #3977:

  • Each sourced URL project gets an incrementing session id as a query parameter
  • Session IDs saved to IndexedDB; Db version migration included
  • Session IDs are reserved by each dartpad instance via atomic transaction before first snapshot write to avoid races to get said id

Future<web.IDBDatabase>? _database;
bool _closed = false;

static const _nextSessionCounterKey = 'next';

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For Reviewer: Keyed the column to enable extending session store later. This just points to the session Id which would be given out next

Comment on lines +45 to +47
final request = web.window.indexedDB.open(databaseName, _currentDatabaseVersion);
request.onupgradeneeded = ((web.IDBVersionChangeEvent event) {
_migrateDatabase(request.result as web.IDBDatabase, fromVersion: event.oldVersion);

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For Reviewer: Since the schema of indexedDB changed with the addition of the sessions table, catch the upgradeneeded event to follow through with database migration

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we are still in preview, dont bother with migrations IMHO

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

final freshId = store.entries.keys.singleWhere((id) => id != 'saved');
await repositories.single.workspaceResourceApi.writeFileFromText('lib/main.dart', 'edited fresh project');
await pumpEventQueue();
await Future<void>.delayed(const Duration(milliseconds: 350));

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For Reviewer: Unrelated fix to have this test actually wait for the edit instead of hanging. Make it 350ms slower, so probably a better way to do this, but oh well for now

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this also fixes the failing CI test on #3991

Comment on lines +149 to +152
// Re-opening the same sourced URL without its `s` session id (e.g. a second
// tab, modeled here as a fresh App instance over the same store) must
// not reuse the first session id.
tester.pumpComponent(app('?sample=counter'));

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For Reviewer: We need to test if a second app instance get a new session id. This is the simplest way I could think of doing so, any other way that you can see?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For Reviewer: Went with storing the session Id counter in the DB over local storage to avoid races, keep the two persistence data in the same place, and avoid having to use a synchronous api

dtetruash-nl and others added 2 commits October 12, 2026 09:14
_projectUri was only read by the restoreProject closure removed in
96ffc77. Drop the field and the unused dartpad_editor import.

Co-Authored-By: Claude Code <noreply@anthropic.com>
- Each sourced URL project gets an incrementing session id as a query
parameter
- Session IDs saved to IndexedDB; Db version migration included
@dtetruash-nl
dtetruash-nl force-pushed the dartpad-preview-introduce-project-persistence-session-ids branch from a8d5a35 to 00eccd0 Compare October 12, 2026 07:17
@dtetruash-nl
dtetruash-nl added this pull request to stack #4008 October 12, 2026 09:19
/// Reflects a freshly minted session id in the address bar without pushing a
/// new history entry, so back navigation does not land on the bare URL.
void _writeSessionIdToUrl(Uri uri, int sessionId) {
final query = {...uri.queryParameters, sessionIdQueryParameter: '$sessionId'};

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

queryParameters keeps only one value per key, but we support repeated file parameters. For example, opening ?sample=counter&file=a.dart&file=b.dart rewrites the URL with only one of those files. Reloading then changes the requested tabs.
Use queryParametersAll instead and add s.

@dtetruash-nl dtetruash-nl Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch, but would this mean that the same source with a different set of open files would count as a separate workspace? I think that what files are open should not dictate that, and only the source should. WDYT?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No I would not count them separate, I agree. Just don't loose them on a refresh

@dtetruash-nl
dtetruash-nl force-pushed the dartpad-preview-introduce-project-persistence-session-ids branch from 1783af3 to 0be8bb3 Compare October 12, 2026 12:14
@dtetruash-nl
dtetruash-nl force-pushed the dartpad-preview-introduce-project-persistence-session-ids branch from 0be8bb3 to 9092fb9 Compare October 12, 2026 13:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants