Files
mnote/rust/crates/mnote-web/browser/local-folder-event-bus-runtime.js
T

726 lines
28 KiB
JavaScript

(function(){
'use strict';
if (window.__mnoteLocalFolderEventBus) {
return;
}
var connections = new Map();
var sidebarRefreshQueues = new Map();
var fileChangeQueues = new Map();
var lastSource = '';
var lastReason = '';
var lastFileChangeDiagnostics = {
source: '',
changedCount: 0,
droppedCount: 0,
lastReaction: '',
lastBatchSchema: ''
};
function root() {
return document.documentElement;
}
function setDiagnostics(source, reason) {
lastSource = source || lastSource || '';
lastReason = reason || lastReason || '';
root().setAttribute('data-mnote-local-folder-event-bus', 'ready');
root().setAttribute('data-mnote-local-folder-event-bus-connections', String(connections.size));
root().setAttribute('data-mnote-local-folder-event-bus-last-source', lastSource);
root().setAttribute('data-mnote-local-folder-event-bus-last-reason', lastReason);
root().setAttribute('data-mnote-file-change-service', 'ready');
root().setAttribute('data-mnote-file-change-service-last-source', lastFileChangeDiagnostics.source || lastSource);
root().setAttribute('data-mnote-file-change-service-last-count', String(lastFileChangeDiagnostics.changedCount || 0));
root().setAttribute('data-mnote-file-change-service-dropped-count', String(lastFileChangeDiagnostics.droppedCount || 0));
root().setAttribute('data-mnote-file-change-service-last-reaction', lastFileChangeDiagnostics.lastReaction || '');
}
function normalizeRootUri(rootUri) {
return String(rootUri || '').trim();
}
function normalizeWorkspaceId(workspaceId) {
return String(workspaceId || 'default').trim() || 'default';
}
function emit(name, detail) {
window.dispatchEvent(new CustomEvent(name, { detail: detail || {} }));
}
function parseEventPayload(event) {
try {
return JSON.parse((event && event.data) || '{}') || {};
} catch (_) {
return {};
}
}
function revisionOf(payload, event) {
return payload.revision || payload.cursor || (event && event.lastEventId) || null;
}
function arrayOf(value) {
if (!value) return [];
if (Array.isArray(value)) return value.filter(Boolean).map(String);
return [String(value)].filter(Boolean);
}
function safeNow() {
return Date.now ? Date.now() : new Date().getTime();
}
function decodeFileUriPath(rootUri) {
var value = String(rootUri || '').trim();
if (!value) return '';
try {
var url = new URL(value);
if (url.protocol !== 'file:') return '';
return decodeURIComponent(url.pathname || '').replace(/\/+$/, '');
} catch (_) {
return '';
}
}
function normalizeSlashes(value) {
return String(value || '').trim().replace(/\\/g, '/');
}
function rootRelativePath(rawPath, rootUri) {
var value = normalizeSlashes(rawPath).replace(/^file:\/\//, '');
if (!value) return '';
if (/^[A-Za-z]:\//.test(value) || value.charAt(0) === '/') {
var rootPath = normalizeSlashes(decodeFileUriPath(rootUri));
if (rootPath && (value === rootPath || value.indexOf(rootPath + '/') === 0)) {
return value.slice(rootPath.length).replace(/^\/+/, '');
}
return '';
}
return value.replace(/^\/+/, '');
}
function localMarkdownDocumentId(relativePath) {
var normalized = normalizeSlashes(relativePath).replace(/^\/+/, '');
if (!/\.md(?:own)?$/i.test(normalized)) return '';
return 'local-md:' + normalized.replace(/\//g, '~2F');
}
function normalizeChangeType(item, fallback) {
var raw = String(
(item && (item.changeType || item.change_type || item.eventKind || item.event_kind || item.kind))
|| fallback
|| 'modified'
).trim();
if (/remove|delete/i.test(raw)) return 'deleted';
if (/create/i.test(raw)) return 'created';
if (/rename|name/i.test(raw)) return 'renamed';
return 'modified';
}
function resourceKindForPath(relativePath) {
return /\.md(?:own)?$/i.test(String(relativePath || '')) ? 'markdown' : 'resource';
}
function normalizeFileChangeItem(item, context) {
var source = String((context && context.source) || (item && item.source) || 'watcher').trim() || 'watcher';
var rootUri = normalizeRootUri((context && context.rootUri) || (item && item.rootUri));
var workspaceId = normalizeWorkspaceId((context && context.workspaceId) || (item && item.workspaceId));
var rawPath = typeof item === 'string'
? item
: String(item && (
item.relativePath
|| item.relative_path
|| item.path
|| item.sourcePath
|| item.source_path
|| item.filePath
|| item.file_path
) || '');
var relativePath = rootRelativePath(rawPath, rootUri);
if (!relativePath) {
return { dropped: true, reason: 'outside_root_or_empty_path', rawPath: rawPath };
}
var eventKind = String(item && (item.eventKind || item.event_kind || item.kind || item.changeType || item.change_type) || '').trim();
var documentId = String(item && (item.documentId || item.document_id) || '').trim() || localMarkdownDocumentId(relativePath);
var observedFileVersion = String(item && (item.observedFileVersion || item.observed_file_version || '') || '').trim();
var bufferFileVersion = String(item && (item.bufferFileVersion || item.buffer_file_version || '') || '').trim();
var fileVersion = String(item && (item.fileVersion || item.file_version || '') || '').trim()
|| observedFileVersion
|| bufferFileVersion
|| String(item && item.revision || (context && context.revision) || '').trim();
return {
schema: 'mnote.file_change.v1',
rootUri: rootUri,
workspaceId: workspaceId,
relativePath: relativePath,
documentId: documentId,
resourceKind: String(item && (item.resourceKind || item.resource_kind) || resourceKindForPath(relativePath)),
changeType: normalizeChangeType(item, eventKind),
eventKind: eventKind,
fileVersion: fileVersion,
source: source,
selfWriteEcho: Boolean(item && (item.selfWriteEcho || item.self_write_echo)),
observedFileVersion: observedFileVersion,
bufferFileVersion: bufferFileVersion,
lastWriteIntentId: String(item && (item.lastWriteIntentId || item.last_write_intent_id || '') || '').trim(),
lastSaveOperationId: String(item && (item.lastSaveOperationId || item.last_save_operation_id || '') || '').trim(),
createdAt: Number(item && (item.createdAt || item.created_at) || safeNow())
};
}
function standardBatchToCompatPayload(batch) {
return {
schema: 'mnote.local_folder.watch_batch.v1',
kind: 'watch_batch',
sourceKind: 'local_folder',
source: batch.source,
rootUri: batch.rootUri,
workspaceId: batch.workspaceId,
revision: batch.revision,
changedPaths: batch.changes.map(function(change) {
return {
relativePath: change.relativePath,
documentId: change.documentId,
kind: change.eventKind || change.changeType,
eventKind: change.eventKind || change.changeType,
changeType: change.changeType,
revision: change.fileVersion || batch.revision,
fileVersion: change.fileVersion,
observedFileVersion: change.observedFileVersion,
bufferFileVersion: change.bufferFileVersion,
lastWriteIntentId: change.lastWriteIntentId,
lastSaveOperationId: change.lastSaveOperationId,
selfWriteEcho: change.selfWriteEcho,
source: change.source
};
}),
affectedParents: batch.affectedParents,
eventKinds: Array.from(new Set(batch.changes.map(function(change) {
return change.eventKind || change.changeType || '';
}).filter(Boolean))),
fallbackResync: batch.resyncRequired === true
};
}
function normalizeFileChangeBatch(entry, event, payload, meta) {
var revision = revisionOf(payload, event);
var source = String((meta && meta.source) || payload.source || payload.sourceKind || 'watcher_sse').trim() || 'watcher_sse';
var reason = String((meta && meta.reason) || payload.reason || 'watch_batch').trim() || 'watch_batch';
var rootUri = normalizeRootUri((entry && entry.rootUri) || payload.rootUri);
var workspaceId = normalizeWorkspaceId((entry && entry.workspaceId) || payload.workspaceId);
var raw = []
.concat(Array.isArray(payload.changedPaths) ? payload.changedPaths : [])
.concat(Array.isArray(payload.changed_paths) ? payload.changed_paths : [])
.concat(Array.isArray(payload.paths) ? payload.paths : [])
.concat(Array.isArray(payload.events) ? payload.events : []);
if (!raw.length && payload.relativePath) raw.push(payload);
var dropped = [];
var changes = [];
raw.forEach(function(item) {
var normalized = normalizeFileChangeItem(item, {
source: source,
rootUri: rootUri,
workspaceId: workspaceId,
revision: revision
});
if (normalized && normalized.dropped) {
dropped.push(normalized);
} else if (normalized) {
changes.push(normalized);
}
});
var affectedParents = collectAffectedParents(payload).map(function(parent) {
return { relativePath: parent, reason: reason };
});
changes.forEach(function(change) {
var parent = change.relativePath.indexOf('/') >= 0 ? change.relativePath.split('/').slice(0, -1).join('/') : '';
if (!affectedParents.some(function(item) { return item.relativePath === parent; })) {
affectedParents.push({ relativePath: parent, reason: reason });
}
});
return {
schema: 'mnote.file_change_batch.v1',
rootUri: rootUri,
workspaceId: workspaceId,
source: source,
reason: reason,
changes: changes,
affectedParents: affectedParents,
revision: revision,
dropped: dropped,
resyncRequired: payload.fallbackResync === true
|| payload.requiresResync === true
|| payload.resyncRequired === true
|| payload.resync_required === true,
rawPayload: payload,
bootstrap: entry && entry.bootstrap || null
};
}
function mergeFileChange(existing, change) {
if (!existing) return change;
return Object.assign({}, existing, change, {
source: change.source || existing.source,
selfWriteEcho: change.selfWriteEcho === true ? true : (change.selfWriteEcho === false ? false : existing.selfWriteEcho),
observedFileVersion: change.observedFileVersion || existing.observedFileVersion,
bufferFileVersion: change.bufferFileVersion || existing.bufferFileVersion,
fileVersion: change.fileVersion || existing.fileVersion,
createdAt: Math.max(Number(existing.createdAt || 0), Number(change.createdAt || 0))
});
}
function fileChangeQueueKey(batch) {
return [batch.rootUri || '', batch.workspaceId || 'default'].join('#');
}
function enqueueFileChangeBatch(batch) {
if (!batch || !batch.rootUri) return;
var key = fileChangeQueueKey(batch);
var queue = fileChangeQueues.get(key);
if (!queue) {
queue = {
rootUri: batch.rootUri,
workspaceId: batch.workspaceId,
sources: new Set(),
reasons: new Set(),
revisions: new Set(),
changes: new Map(),
affectedParents: new Map(),
dropped: [],
resyncRequired: false,
bootstrap: batch.bootstrap || null,
timer: 0
};
fileChangeQueues.set(key, queue);
}
if (batch.source) queue.sources.add(batch.source);
if (batch.reason) queue.reasons.add(batch.reason);
if (batch.revision) queue.revisions.add(String(batch.revision));
queue.dropped = queue.dropped.concat(batch.dropped || []);
queue.resyncRequired = queue.resyncRequired || batch.resyncRequired === true;
(batch.changes || []).forEach(function(change) {
var changeKey = [change.rootUri || batch.rootUri, change.relativePath, change.fileVersion || ''].join('#');
queue.changes.set(changeKey, mergeFileChange(queue.changes.get(changeKey), change));
});
(batch.affectedParents || []).forEach(function(parent) {
var relativePath = String(parent && parent.relativePath || parent || '');
queue.affectedParents.set(relativePath, {
relativePath: relativePath,
reason: String(parent && parent.reason || batch.reason || 'file-change')
});
});
if (!queue.timer) {
queue.timer = window.setTimeout(function() {
flushFileChangeQueue(key);
}, 80);
}
}
function currentDocumentSessionState(change) {
var snapshot = null;
try {
snapshot = window.__mnoteDebugDocumentSessions
&& window.__mnoteDebugDocumentSessions.snapshot
&& window.__mnoteDebugDocumentSessions.snapshot();
} catch (_) {
snapshot = null;
}
root().setAttribute('data-mnote-file-change-service-session-api', snapshot ? 'available' : 'unavailable');
var sessions = Array.isArray(snapshot && snapshot.sessions) ? snapshot.sessions : [];
return sessions.find(function(session) {
if (!session || session.sourceKind !== 'local_folder') return false;
if (change.rootUri && session.rootUri && change.rootUri !== session.rootUri) return false;
if (change.documentId && session.documentId === change.documentId) return true;
return false;
}) || null;
}
function reactionTypeForChange(change) {
if (change.selfWriteEcho) return 'ignore_self_write_echo';
if (change.resourceKind !== 'markdown') return 'refresh_resource_tab';
var session = currentDocumentSessionState(change);
if (session && /dirty|external/i.test(String(session.dirtyState || session.status || ''))) {
return 'external_conflict_current_document';
}
if (session) return 'refresh_current_document';
if (change.changeType === 'created' || change.changeType === 'deleted' || change.changeType === 'renamed') {
return 'refresh_page_tree_projection';
}
return 'refresh_filetree_parents';
}
function emitFileChangeReactions(detail) {
var reactionTypes = new Set();
(detail.fileChangeBatch.changes || []).forEach(function(change) {
var type = reactionTypeForChange(change);
reactionTypes.add(type);
emit('mnote:file-change-reaction', {
schema: 'mnote.file_change_reaction.v1',
type: type,
rootUri: detail.rootUri,
workspaceId: detail.workspaceId,
source: detail.source,
change: change,
batch: detail.fileChangeBatch
});
});
if (detail.affectedParents && detail.affectedParents.length) {
reactionTypes.add('refresh_filetree_parents');
}
lastFileChangeDiagnostics.lastReaction = Array.from(reactionTypes).join(',') || '';
root().setAttribute('data-mnote-file-change-service-last-reaction', lastFileChangeDiagnostics.lastReaction);
return reactionTypes;
}
function flushFileChangeQueue(key) {
var queue = fileChangeQueues.get(key);
if (!queue) return;
fileChangeQueues.delete(key);
var sources = Array.from(queue.sources);
var reasons = Array.from(queue.reasons);
var revision = Array.from(queue.revisions).pop() || null;
var batch = {
schema: 'mnote.file_change_batch.v1',
rootUri: queue.rootUri,
workspaceId: queue.workspaceId,
source: sources.join(',') || 'watcher',
reason: reasons.join(',') || 'watch_batch',
changes: Array.from(queue.changes.values()),
affectedParents: Array.from(queue.affectedParents.values()),
revision: revision,
dropped: queue.dropped,
resyncRequired: queue.resyncRequired
};
var compatPayload = standardBatchToCompatPayload(batch);
var detail = {
schema: 'mnote.local_folder.event_bus.watch_batch.v1',
source: batch.source,
reason: batch.reason,
rootUri: batch.rootUri,
workspaceId: batch.workspaceId,
revision: batch.revision,
payload: compatPayload,
bootstrap: queue.bootstrap || null,
changedPaths: compatPayload.changedPaths,
affectedParents: batch.affectedParents,
fileChangeBatch: batch,
resyncRequired: batch.resyncRequired,
viaEventBus: true
};
lastFileChangeDiagnostics = {
source: batch.source,
changedCount: batch.changes.length,
droppedCount: batch.dropped.length,
lastReaction: '',
lastBatchSchema: batch.schema
};
setDiagnostics(batch.source, batch.reason);
root().setAttribute('data-mnote-tree-live-revision', String(batch.revision || ''));
root().setAttribute('data-mnote-file-change-service-last-schema', batch.schema);
emit('mnote:file-change-batch', batch);
emit('mnote:local-folder:watch-batch', detail);
emit('tree:local-folder-watch-batch', detail);
var reactionTypes = emitFileChangeReactions(detail);
if (batch.affectedParents.length > 0 || reactionTypes.has('refresh_filetree_parents')) {
emit('mnote:local-folder:filetree-parent-changed', detail);
}
if (batch.changes.length > 0) {
emit('mnote:local-folder:document-changed', detail);
emit('mnote:local-folder:resource-changed', detail);
emit('mnote:local-folder:knowledge-rag-source-updated', detail);
}
queueSidebarRefresh(detail);
if (batch.resyncRequired) {
emit('mnote:local-folder:resync-required', detail);
}
}
function pathArrayOf(value) {
if (!value) return [];
var list = Array.isArray(value) ? value : [value];
return list.map(function(item) {
if (typeof item === 'string') return item.trim();
if (!item || typeof item !== 'object') return '';
return String(item.relativePath || item.relative_path || item.path || item.sourcePath || item.source_path || '').trim();
}).filter(Boolean);
}
function collectChangedPaths(payload) {
var paths = []
.concat(pathArrayOf(payload.changedPaths))
.concat(pathArrayOf(payload.changed_paths))
.concat(pathArrayOf(payload.paths));
var events = Array.isArray(payload.events) ? payload.events : [];
events.forEach(function(item) {
if (!item || typeof item !== 'object') return;
paths = paths
.concat(arrayOf(item.path))
.concat(arrayOf(item.relativePath))
.concat(arrayOf(item.relative_path))
.concat(arrayOf(item.sourcePath))
.concat(arrayOf(item.source_path));
});
return Array.from(new Set(paths));
}
function collectChangedPathItems(payload, reason) {
var raw = []
.concat(Array.isArray(payload.changedPaths) ? payload.changedPaths : [])
.concat(Array.isArray(payload.changed_paths) ? payload.changed_paths : [])
.concat(Array.isArray(payload.paths) ? payload.paths : [])
.concat(Array.isArray(payload.events) ? payload.events : []);
var seen = new Set();
var items = [];
raw.forEach(function(item) {
var relativePath = typeof item === 'string'
? item.trim()
: String(item && (item.relativePath || item.relative_path || item.path || item.sourcePath || item.source_path || '') || '').trim();
if (!relativePath || seen.has(relativePath)) return;
seen.add(relativePath);
items.push({
relativePath: relativePath,
reason: reason || 'event-bus',
kind: typeof item === 'object' && item ? String(item.kind || '') : '',
eventKind: typeof item === 'object' && item ? String(item.eventKind || item.event_kind || item.changeType || item.change_type || '') : ''
});
});
if (items.length) return items;
return pathItems(collectChangedPaths(payload), reason);
}
function collectAffectedParents(payload) {
var parents = []
.concat(pathArrayOf(payload.affectedParents))
.concat(pathArrayOf(payload.affected_parents))
.concat(pathArrayOf(payload.parentRelativePaths))
.concat(pathArrayOf(payload.parent_relative_paths));
return Array.from(new Set(parents));
}
function pathItems(paths, reason) {
return (paths || []).map(function(relativePath) {
return {
relativePath: String(relativePath || '').trim(),
reason: reason || 'event-bus'
};
}).filter(function(item) { return item.relativePath || item.relativePath === ''; });
}
function queueSidebarRefresh(detail) {
var key = String(detail.rootUri || '').trim();
if (!key) return;
var queue = sidebarRefreshQueues.get(key);
if (!queue) {
queue = {
rootUri: detail.rootUri,
workspaceId: detail.workspaceId,
revisions: new Set(),
reasons: new Set(),
changedPaths: new Map(),
affectedParents: new Set(),
resyncRequired: false,
timer: 0
};
sidebarRefreshQueues.set(key, queue);
}
if (detail.revision) queue.revisions.add(String(detail.revision));
if (detail.reason) queue.reasons.add(String(detail.reason));
(detail.changedPaths || []).forEach(function(item) {
var path = typeof item === 'string' ? item : String(item && (item.relativePath || item.relative_path || '') || '');
if (!path && path !== '') return;
var existing = queue.changedPaths.get(path) || { relativePath: path };
queue.changedPaths.set(path, {
relativePath: path,
reason: String((item && item.reason) || existing.reason || detail.reason || 'event-bus-orchestrated'),
kind: String((item && item.kind) || existing.kind || ''),
eventKind: String((item && item.eventKind) || (item && item.event_kind) || existing.eventKind || '')
});
});
(detail.affectedParents || []).forEach(function(item) {
var parent = typeof item === 'string' ? item : String(item && (item.relativePath || item.relative_path || '') || '');
if (parent || parent === '') queue.affectedParents.add(parent);
});
queue.resyncRequired = queue.resyncRequired || detail.resyncRequired === true;
if (!queue.timer) {
queue.timer = window.setTimeout(function() {
flushSidebarRefresh(key);
}, 0);
}
root().setAttribute('data-mnote-local-folder-event-bus-sidebar-refresh-pending', String(queue.affectedParents.size));
}
function flushSidebarRefresh(key) {
var queue = sidebarRefreshQueues.get(key);
if (!queue) return;
sidebarRefreshQueues.delete(key);
var reasons = Array.from(queue.reasons);
var detail = {
schema: 'mnote.local_folder.event_bus.sidebar_refresh.v1',
source: 'event_bus_orchestrator',
reason: reasons.join(',') || 'watch_batch',
rootUri: queue.rootUri,
workspaceId: queue.workspaceId,
revision: Array.from(queue.revisions).pop() || null,
reasons: reasons,
changedPaths: Array.from(queue.changedPaths.values()),
affectedParents: pathItems(Array.from(queue.affectedParents), 'event-bus-orchestrated'),
resyncRequired: queue.resyncRequired,
viaEventBus: true
};
root().setAttribute('data-mnote-local-folder-event-bus-sidebar-refresh-applied', detail.reason);
root().setAttribute('data-mnote-local-folder-event-bus-sidebar-refresh-parents', String(detail.affectedParents.length));
emit('mnote:local-folder:sidebar-refresh-requested', detail);
}
function dispatchWatchBatch(entry, event, payload, meta) {
enqueueFileChangeBatch(normalizeFileChangeBatch(entry, event, payload, meta));
}
function closeEntry(entry) {
if (!entry || !entry.source || typeof entry.source.close !== 'function') return;
entry.source.close();
}
function startLocalFolderWatcher(options) {
var rootUri = normalizeRootUri(options && options.rootUri);
if (!rootUri || typeof window.EventSource !== 'function') return null;
var workspaceId = normalizeWorkspaceId(options && options.workspaceId);
var key = rootUri;
if (connections.has(key)) {
var existing = connections.get(key);
if ((!existing.workspaceId || existing.workspaceId === 'default') && workspaceId && workspaceId !== 'default') {
existing.workspaceId = workspaceId;
if (existing.handle) existing.handle.workspaceId = workspaceId;
}
setDiagnostics(existing.lastSource || 'watcher_sse', 'reuse_connection');
return existing.handle;
}
var url = new URL('/api/local-folder/events', window.location.origin);
url.searchParams.set('rootUri', rootUri);
url.searchParams.set('treeLive', 'true');
var eventSource = new EventSource(url.toString());
var entry = {
key: key,
rootUri: rootUri,
workspaceId: workspaceId,
bootstrap: (options && options.bootstrap) || null,
source: eventSource,
lastSource: 'watcher_sse',
close: function() {
connections.delete(key);
closeEntry(entry);
setDiagnostics('watcher_sse', 'closed');
}
};
entry.handle = {
key: key,
rootUri: rootUri,
workspaceId: workspaceId,
source: eventSource,
close: entry.close
};
connections.set(key, entry);
setDiagnostics('watcher_sse', 'connect');
emit('mnote:local-folder:event-bus-ready', {
schema: 'mnote.local_folder.event_bus.ready.v1',
source: 'watcher_sse',
reason: 'connect',
rootUri: rootUri,
workspaceId: workspaceId,
connections: connections.size
});
eventSource.addEventListener('open', function() {
setDiagnostics('watcher_sse', 'open');
});
eventSource.addEventListener('watch_batch', function(event) {
dispatchWatchBatch(entry, event, parseEventPayload(event), {
source: 'watcher_sse',
reason: 'watch_batch'
});
});
eventSource.addEventListener('tree_error', function(event) {
var payload = parseEventPayload(event);
setDiagnostics('watcher_sse', 'tree_error');
emit('tree:error', { payload: payload, bootstrap: entry.bootstrap || null, viaEventBus: true });
});
eventSource.onerror = function() {
setDiagnostics('watcher_sse', 'error');
};
return entry.handle;
}
function emitSyntheticWatchBatch(detail) {
var payload = detail && detail.payload ? detail.payload : (detail || {});
var rootUri = normalizeRootUri(detail && detail.rootUri);
var workspaceId = normalizeWorkspaceId(detail && detail.workspaceId);
var entry = {
rootUri: rootUri,
workspaceId: workspaceId,
bootstrap: (detail && detail.bootstrap) || null
};
dispatchWatchBatch(entry, { lastEventId: detail && detail.revision }, payload, {
source: (detail && detail.source) || 'synthetic',
reason: (detail && detail.reason) || payload.source || 'synthetic_watch_batch'
});
}
function emitChangedFiles(detail) {
var payload = detail && detail.payload && typeof detail.payload === 'object' ? detail.payload : {};
var changedFiles = []
.concat(Array.isArray(detail && detail.changedFiles) ? detail.changedFiles : [])
.concat(Array.isArray(payload.changedFiles) ? payload.changedFiles : [])
.concat(Array.isArray(payload.changed_files) ? payload.changed_files : []);
if (!changedFiles.length) return;
var rootUri = normalizeRootUri((detail && detail.rootUri) || payload.rootUri);
var workspaceId = normalizeWorkspaceId((detail && detail.workspaceId) || payload.workspaceId);
emitSyntheticWatchBatch({
source: (detail && detail.source) || payload.source || 'changed_files_adapter',
reason: (detail && detail.reason) || payload.reason || 'changed_files_adapter',
rootUri: rootUri,
workspaceId: workspaceId,
payload: {
schema: 'mnote.local_folder.watch_batch.v1',
source: (detail && detail.source) || payload.source || 'changed_files_adapter',
rootUri: rootUri,
workspaceId: workspaceId,
revision: (detail && detail.revision) || payload.revision || null,
changedPaths: changedFiles,
affectedParents: Array.isArray(detail && detail.affectedParents) ? detail.affectedParents : []
}
});
}
function closeAll() {
Array.from(connections.values()).forEach(function(entry) {
closeEntry(entry);
});
connections.clear();
setDiagnostics('watcher_sse', 'closed');
}
window.__mnoteLocalFolderEventBus = {
startLocalFolderWatcher: startLocalFolderWatcher,
emitSyntheticWatchBatch: emitSyntheticWatchBatch,
emitChangedFiles: emitChangedFiles,
closeAll: closeAll,
flushSidebarRefresh: function(rootUri) {
flushSidebarRefresh(normalizeRootUri(rootUri));
},
connectionCount: function() { return connections.size; },
diagnostics: function() {
return {
connections: connections.size,
lastSource: lastSource,
lastReason: lastReason,
fileChange: Object.assign({}, lastFileChangeDiagnostics)
};
}
};
setDiagnostics('', 'ready');
})();