imdone-core 2.3.3 → 2.3.5
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.
- package/CHANGELOG.md +4 -0
- package/_index.md +0 -1
- package/imdone-core-2.3.4.tgz +0 -0
- package/lib/default-filtered-move-position.js +36 -0
- package/lib/index.js +1 -0
- package/lib/mixins/repo-watched-fs-store.js +48 -19
- package/lib/project.js +12 -0
- package/lib/repository.js +1 -1
- package/package.json +1 -1
- package/types/default-filtered-move-position.d.ts +7 -0
- package/types/index.d.ts +1 -0
- package/types/project.d.ts +1 -0
- package/.imdone-cli.yml +0 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
## 2.3.5
|
|
2
|
+
|
|
3
|
+
- Incorporate newly added watched files into repository state before emitting `file.update`, so live board consumers can render the new task without a reload or restart.
|
|
4
|
+
|
|
1
5
|
## 2.3.3
|
|
2
6
|
|
|
3
7
|
- Update `adm-zip` to `0.6.0` to address a high-severity ZIP parsing memory allocation vulnerability.
|
package/_index.md
CHANGED
|
Binary file
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
function sameTask(left, right) {
|
|
2
|
+
return Boolean(left && right && left.equals(right))
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function resolveDefaultFilteredMovePosition({
|
|
6
|
+
task,
|
|
7
|
+
newList,
|
|
8
|
+
newPosition,
|
|
9
|
+
filteredCards,
|
|
10
|
+
repositoryListCards,
|
|
11
|
+
}) {
|
|
12
|
+
const visibleDestinationCards = filteredCards
|
|
13
|
+
.filter(candidate => candidate.list === newList && !sameTask(candidate, task))
|
|
14
|
+
|
|
15
|
+
if (!Number.isInteger(newPosition)
|
|
16
|
+
|| newPosition < 0
|
|
17
|
+
|| newPosition > visibleDestinationCards.length) {
|
|
18
|
+
throw new RangeError(`Filtered task position is outside ${newList}: ${newPosition}`)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const destinationCards = repositoryListCards
|
|
22
|
+
.filter(candidate => !sameTask(candidate, task))
|
|
23
|
+
if (visibleDestinationCards.length === 0) return destinationCards.length
|
|
24
|
+
|
|
25
|
+
const anchor = visibleDestinationCards[
|
|
26
|
+
Math.min(newPosition, visibleDestinationCards.length - 1)
|
|
27
|
+
]
|
|
28
|
+
const anchorPosition = destinationCards.findIndex(candidate => sameTask(candidate, anchor))
|
|
29
|
+
if (anchorPosition < 0) {
|
|
30
|
+
throw new Error(`Filtered task is missing from ${newList}: ${anchor.id}`)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return newPosition < visibleDestinationCards.length
|
|
34
|
+
? anchorPosition
|
|
35
|
+
: anchorPosition + 1
|
|
36
|
+
}
|
package/lib/index.js
CHANGED
|
@@ -5,6 +5,7 @@ export * from './checksum.js';
|
|
|
5
5
|
export * from './clone.js';
|
|
6
6
|
export * from './config.js';
|
|
7
7
|
export * from './constants.js';
|
|
8
|
+
export * from './default-filtered-move-position.js';
|
|
8
9
|
export * from './default-settings.js';
|
|
9
10
|
export * from './file.js';
|
|
10
11
|
export * from './get-tasks-to-modify.js';
|
|
@@ -19,6 +19,20 @@ export function watchedFileSystemStoreMixin(repo, fs = realFs) {
|
|
|
19
19
|
let initializing = false
|
|
20
20
|
let refreshing = false
|
|
21
21
|
let watcherPaused = false
|
|
22
|
+
const watcherEvents = new Set()
|
|
23
|
+
|
|
24
|
+
function trackWatcherEvent(listener) {
|
|
25
|
+
return (...args) => {
|
|
26
|
+
const event = Promise.resolve().then(() => listener(...args))
|
|
27
|
+
const trackedEvent = event.catch((err) => {
|
|
28
|
+
logger.error('Error processing watcher event')
|
|
29
|
+
logger.error(err)
|
|
30
|
+
repo.emit('watch.error', err)
|
|
31
|
+
})
|
|
32
|
+
watcherEvents.add(trackedEvent)
|
|
33
|
+
void trackedEvent.finally(() => watcherEvents.delete(trackedEvent))
|
|
34
|
+
}
|
|
35
|
+
}
|
|
22
36
|
|
|
23
37
|
function ready() {
|
|
24
38
|
return !initializing && !refreshing
|
|
@@ -80,6 +94,7 @@ export function watchedFileSystemStoreMixin(repo, fs = realFs) {
|
|
|
80
94
|
|
|
81
95
|
repo.destroy = async function () {
|
|
82
96
|
if (repo.watcher) await repo.watcher.close()
|
|
97
|
+
await Promise.allSettled([...watcherEvents])
|
|
83
98
|
await _destroy.apply(repo)
|
|
84
99
|
}
|
|
85
100
|
|
|
@@ -147,7 +162,10 @@ export function watchedFileSystemStoreMixin(repo, fs = realFs) {
|
|
|
147
162
|
persistent: true,
|
|
148
163
|
usePolling: false,
|
|
149
164
|
alwaysStat: true,
|
|
150
|
-
awaitWriteFinish:
|
|
165
|
+
awaitWriteFinish: {
|
|
166
|
+
stabilityThreshold: 200,
|
|
167
|
+
pollInterval: 50,
|
|
168
|
+
},
|
|
151
169
|
atomic: true,
|
|
152
170
|
ignoreInitial: true,
|
|
153
171
|
ignored: (file) => {
|
|
@@ -169,21 +187,23 @@ export function watchedFileSystemStoreMixin(repo, fs = realFs) {
|
|
|
169
187
|
initializing = false
|
|
170
188
|
resolve()
|
|
171
189
|
})
|
|
172
|
-
.on('add', async function (path, stat) {
|
|
190
|
+
.on('add', trackWatcherEvent(async function (path, stat) {
|
|
173
191
|
logger.log('Watcher received add event for file: ' + path)
|
|
174
192
|
if (stat.isDirectory()) return
|
|
175
|
-
|
|
193
|
+
const relativePath = repo.getRelativePath(path)
|
|
194
|
+
let file = repo.getFile(relativePath)
|
|
176
195
|
if (file === undefined) {
|
|
177
196
|
log('Creating file: ' + path)
|
|
178
197
|
file = new File({
|
|
179
198
|
repoId: repo.getId(),
|
|
180
|
-
filePath:
|
|
199
|
+
filePath: relativePath,
|
|
181
200
|
languages: repo.languages,
|
|
182
201
|
project: repo.project,
|
|
183
202
|
})
|
|
184
203
|
}
|
|
185
204
|
|
|
186
|
-
stat = await repo.fileOK()
|
|
205
|
+
stat = await repo.fileOK(relativePath)
|
|
206
|
+
if (!stat) return
|
|
187
207
|
log('fileOK returned: ' + JSON.stringify(stat))
|
|
188
208
|
if (stat.mtime <= file.getModifiedTime()) {
|
|
189
209
|
return log('File update already applied. Change ignored for file: ' + path)
|
|
@@ -192,8 +212,8 @@ export function watchedFileSystemStoreMixin(repo, fs = realFs) {
|
|
|
192
212
|
file = await repo.readFile(file)
|
|
193
213
|
repo.emit('watch.add', file)
|
|
194
214
|
repo.emitFileUpdate(file)
|
|
195
|
-
})
|
|
196
|
-
.on('change', async function (path, stat) {
|
|
215
|
+
}))
|
|
216
|
+
.on('change', trackWatcherEvent(async function (path, stat) {
|
|
197
217
|
logger.log(
|
|
198
218
|
`Watcher received change event for file: ${path} repoPath: ${repo.path}`,
|
|
199
219
|
stat.mtime
|
|
@@ -201,10 +221,10 @@ export function watchedFileSystemStoreMixin(repo, fs = realFs) {
|
|
|
201
221
|
if (!path || stat.isDirectory()) return
|
|
202
222
|
|
|
203
223
|
const relPath = repo.getRelativePath(path)
|
|
204
|
-
if (!initializing && _isImdoneConfig(relPath)) onConfigChange(relPath)
|
|
205
|
-
if (!initializing && _isImdoneIgnore(relPath)) onIgnoreChange(relPath)
|
|
224
|
+
if (!initializing && _isImdoneConfig(relPath)) return onConfigChange(relPath)
|
|
225
|
+
if (!initializing && _isImdoneIgnore(relPath)) return onIgnoreChange(relPath)
|
|
206
226
|
|
|
207
|
-
var file = repo.getFile(path)
|
|
227
|
+
var file = repo.getFile(path)
|
|
208
228
|
const isFile = File.isFile(file)
|
|
209
229
|
// BACKLOG ## Handle the case where the file is not in the repo
|
|
210
230
|
// #urgent #1.12.0
|
|
@@ -216,28 +236,37 @@ export function watchedFileSystemStoreMixin(repo, fs = realFs) {
|
|
|
216
236
|
return
|
|
217
237
|
}
|
|
218
238
|
|
|
219
|
-
const ok = await repo.fileOK(
|
|
239
|
+
const ok = await repo.fileOK(file?.path || path)
|
|
220
240
|
if (!ok) return
|
|
221
241
|
log('Reading file: ' + path)
|
|
222
|
-
if (!isFile)
|
|
242
|
+
if (!isFile) {
|
|
243
|
+
const relativePath = repo.getRelativePath(path)
|
|
244
|
+
file = repo.getFile(relativePath) || new File({
|
|
245
|
+
repoId: repo.getId(),
|
|
246
|
+
filePath: relativePath,
|
|
247
|
+
languages: repo.languages,
|
|
248
|
+
project: repo.project,
|
|
249
|
+
})
|
|
250
|
+
}
|
|
223
251
|
file = await repo.readFile(file)
|
|
224
252
|
repo.emit('watch.change', file)
|
|
225
253
|
repo.emitFileUpdate(file)
|
|
226
|
-
})
|
|
227
|
-
.on('
|
|
254
|
+
}))
|
|
255
|
+
.on('unlink', trackWatcherEvent(async function (path) {
|
|
228
256
|
log('Watcher received unlink event for file: ' + path)
|
|
229
|
-
repo.
|
|
230
|
-
|
|
257
|
+
const relativePath = repo.getRelativePath(path)
|
|
258
|
+
const file = repo.getFile(relativePath) || new File({
|
|
231
259
|
repoId: repo.getId(),
|
|
232
|
-
filePath:
|
|
260
|
+
filePath: relativePath,
|
|
233
261
|
languages: repo.languages,
|
|
234
262
|
project: repo.project,
|
|
235
263
|
})
|
|
236
|
-
|
|
264
|
+
repo.removeFilePath(relativePath)
|
|
265
|
+
log('Removing file: ' + relativePath)
|
|
237
266
|
repo.removeFile(file)
|
|
238
267
|
repo.emit('watch.delete', file)
|
|
239
268
|
repo.emitFileUpdate(file, true)
|
|
240
|
-
})
|
|
269
|
+
}))
|
|
241
270
|
});
|
|
242
271
|
}
|
|
243
272
|
|
package/lib/project.js
CHANGED
|
@@ -21,6 +21,7 @@ import { renderMarkdown, extractWikilinkTopics } from './adapters/markdown.js';
|
|
|
21
21
|
import { getFunctionSignature } from './adapters/parsers/function-parser.js';
|
|
22
22
|
import { format } from './adapters/parsers/content-transformer.js';
|
|
23
23
|
import { logger } from './adapters/logger.js';
|
|
24
|
+
import { resolveDefaultFilteredMovePosition } from './default-filtered-move-position.js';
|
|
24
25
|
|
|
25
26
|
function calculateTotals(lists = []) {
|
|
26
27
|
const totals = {}
|
|
@@ -459,6 +460,17 @@ export class WorkerProject extends Project {
|
|
|
459
460
|
return await this.repo.moveTask({task, newList, newPos})
|
|
460
461
|
}
|
|
461
462
|
|
|
463
|
+
async moveTaskInDefaultFilteredCards(task, newList, newPos) {
|
|
464
|
+
const repositoryPosition = resolveDefaultFilteredMovePosition({
|
|
465
|
+
task,
|
|
466
|
+
newList,
|
|
467
|
+
newPosition: newPos,
|
|
468
|
+
filteredCards: this.getDefaultFilteredCards(),
|
|
469
|
+
repositoryListCards: this.repo.getTasksInList(newList),
|
|
470
|
+
})
|
|
471
|
+
return await this.repo.moveTask({task, newList, newPos: repositoryPosition})
|
|
472
|
+
}
|
|
473
|
+
|
|
462
474
|
getFile(filePath) {
|
|
463
475
|
return this.repo.getFile(filePath)
|
|
464
476
|
}
|
package/lib/repository.js
CHANGED
package/package.json
CHANGED
package/types/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export * from "./checksum.js";
|
|
|
5
5
|
export * from "./clone.js";
|
|
6
6
|
export * from "./config.js";
|
|
7
7
|
export * from "./constants.js";
|
|
8
|
+
export * from "./default-filtered-move-position.js";
|
|
8
9
|
export * from "./default-settings.js";
|
|
9
10
|
export * from "./file.js";
|
|
10
11
|
export * from "./get-tasks-to-modify.js";
|
package/types/project.d.ts
CHANGED
|
@@ -79,6 +79,7 @@ export class WorkerProject {
|
|
|
79
79
|
addTag(task: any, tag: any): Promise<any>;
|
|
80
80
|
removeTag(task: any, tag: any): Promise<any>;
|
|
81
81
|
moveTask(task: any, newList: any, newPos: any): Promise<any>;
|
|
82
|
+
moveTaskInDefaultFilteredCards(task: any, newList: any, newPos: any): Promise<any>;
|
|
82
83
|
getFile(filePath: any): any;
|
|
83
84
|
getFileForTask(task: any): any;
|
|
84
85
|
rollBackFileForTask(task: any): any;
|
package/.imdone-cli.yml
DELETED