Lifecycle
Initialization
Summary
- check if we are in a dendron workspace
- workspace can be a code workspace (a .code-workspace file) or a native workspace (folder with dendron.yml)
- depending on what sort of workspace we're in, Dendron will instantiate either a Dendron[Native|Code]Workspace
- if multiple folders have
dendron.yml
, dendron will resolve to the first one found. logic here
- if multiple folders have
- start engine server (local server that does indexing)
- the engine server is spawned in a separate process
- NOTE: if in DEV mode (when launching plugin using vscode build task), we do not spawn a separate process
- reload workspace (connect to the local server)
- activate file watchers
Components
Steps
Dendron Workspace Created
An instance of DendronWorkspace is created near the beginning of activation. This is a singleton god object that exists as long as Dendron is running. The only requirement for initialization is the location of Dendron's workspace root. Example initilization below
new DendronCodeWorkspace({
wsRoot: path.dirname(DendronExtension.workspaceFile().fsPath),
logUri: context.logUri,
assetUri,
});
Keep in mind that with Native Workspaces,
the root of the VSCode workspace may not be the root of the Dendron workspace.
If the dendron.yml
file is located in a subdirectory of the root, then that
directory is the root for Dendron. Use findWSRootInWorkspaceFolders
to find
the actual root.
Check for workspace
_activate {
stateService := new StateService
initializeSentry
ws := DendronExtension.getOrCreate
_setupCommands
_setupLanguageFeatures
extensionInstallStatus :=
if extensionInstallStatus = INITIAL_INSTALL
MetadataService.setInitialInstall
// do this if we're in a dendron workspace
if isDendronWorkspace {
activator = new WorkspaceActivator
activator.activate
// do logic depending on if its native workspace vs code workspace
...
setupTraits
setupSegmentWithCacheFlush
// see [[Migration|dendron://dendron.docs/pkg.dendron-engine.t.migration]]
changes = runMigrationsIfNecessary
if !changes {
runConfigMigrationIfNecessary
}
Sentry.setUser
wsService.initialize
wsService.writeMeta
// ---
showInitProgress {
port = startServerProcess
updateEngineAPI(port)
if !webUI {
treeView = new NativeTreeView
context.subscriptions.push treeView
}
ws.reloadWorkspace // 312
// custom set context logic
...
MetadataService.setDendronWorkspaceActivated
_setupCommands
AnalyticsUtils.identify
if InstallStatus.INITIAL_INSTALL warnIncompatibleExtensions
ws.activateWatchers // [[Lifecycle|dendron://dendron.docs/pkg.plugin-core.ref.watchers.arch.lifecycle]]
togglePluginActiveContext
}
} else {
autoInit = new FileAddWatcher
}
// initial install logic
if InstallStatus.INITIAL_INSTALL {
...
}
showWelcomeOrWhatsNew
if DendronExtension.isActive {
HistoryService.instance().add(extension, activate)
// If automaticallyShowPreview = true, display preview panel on start up
}
}
Reload Workspace
- src/commands/ReloadIndex.ts
// 49
reloadWorkspace {
ws.reloadWorkspace
if isFirstInstall {
showTutorial
}
postReloadWorkspace
emit(extension, initialized)
}
postReloadWorkspace
postReloadWorkspace {
previousWsVersion = config.get(WORKSPACE_STATE.WS_VERSION)
if previousWsVersion == 0.0.0 {
execute(Upgrade)
config.set(WORKSPACE_STATE.WS_VERSION, ws.version)
} else {
newVersion :=
if (newVersion > previousWsVersion) {
execute(Upgrade)
config.set(WORKSPACE_STATE.WS_VERSION, ws.version)
emit(extension, upgraded)
}
}
}
showWelcome
showWelcomeOrWhatsNew {
switch(extensionInstallStatus) {
case INITIAL_INSTALL {
showWelcome
}
....
}
}
showWelcome {
welcomeContent :=
view = createWebviewPanel(welcomeContent)
view.on(msg => {
switch(msg {
case initializeWorkspace {
LaunchTutorialWorkspaceCommand.run
}
})
})
}
Reference
getOrCreate
if !_DendronWorkspace
_DendronWorkspace = new DendronWorkspace
constructor {
@_setupCommands
...
}
activator.activate
if (NATIVE) {
activateNativeWorkspace;
} else {
activateCodeWorkspace;
}
activateCodeWorkspace {
new DendronCodeWorkspace
}
class DendronCodeWorkspace extends DendronBaseWorkspace {
constructor {
}
}
startServerProcess
- file: src/_extension.ts:
- related: launch (Private)
startServer {
maybePort :=
if !maybePort {
launch()
}
}
updateEngineAPI
- src/utils.ts
WSUtils.updateEngineAPI {
EngineAPIService.updateEngineAPI(
vaults,
wsRoot
)
}
class EngineAPIService {
create {
const vaults =
DendronWorkspace.instance().vaults?.map((ent) => ent.fsPath) || [];
DendronEngineClient.create({ vaults, ws, port, history })
}
}
workspace.vaults
get vaults {
}
ws.reloadWorkspace
executeCommand(RELOAD_INDEX);
setupLanguageFeatures
_setupLanguageFeatures {
registerReferenceProvider;
registerDefinitionProvider;
registerHoverProvider;
registerFoldingRangeProvider
}
Workspace Creation
This describes everything that happens after a user runs Initialize Workspace
. See source code here.
Running a Command
When a command is executed, it runs the following functions in order. Source code here
- sanityCheck: does basic checks
- enrichInputs: cleans up passed in inputs
- execute: runs the actual command
- showResponse: show response to the user
Activate
-
activating dendron involves the following steps
- dendron api server started
- dendron engine finish indexing notes
-
extension, initialized: engine is loaded
-
other
- extension, not_initialized: error with starting engine
Related
Children
Backlinks