Skip to content

Commit 60f488d

Browse files
committed
more fixes
1 parent ce750e4 commit 60f488d

2 files changed

Lines changed: 30 additions & 22 deletions

File tree

src/reader-watch.js

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,29 @@ import { Reader } from 'styled-map-package'
55

66
import { noop } from './utils.js'
77

8+
const isWin = process.platform === 'win32'
9+
810
/**
911
* Returns a function to get a reader instance that will change when file at the given filepath is changed.
1012
*
1113
* @param {string} filePath Path to the SMP file
1214
* @param {Object} [options]
1315
* @param {AbortSignal} [options.signal] Optional AbortSignal to close the reader when aborted
14-
* @returns {(() => Reader) & { close: () => Promise<void> }} Function that returns the current Reader instance, with a close() method to clean up the watcher and reader
16+
* @returns {(() => Promise<Reader>) & { close: () => Promise<void> }} Function that returns the current Reader instance, with a close() method to clean up the watcher and reader
1517
*/
1618
export function createReaderWatch(filePath, { signal } = {}) {
1719
const dir = path.dirname(filePath)
1820
let { reader, readerClose } = initializeReader()
1921
const watcher = fs.watch(
2022
dir,
2123
{ signal, persistent: false },
22-
async (_, filename) => {
24+
(_, filename) => {
2325
console.log(`File change '${_}' detected: ${filename}`)
2426
// If filename is null (which can happen on some platforms), or if the
2527
// changed file is the one we're watching, then we re-create the reader
2628
if (filename && filename !== path.basename(filePath)) return
2729
signal?.removeEventListener('abort', readerClose)
28-
await readerClose()
30+
readerClose()
2931
;({ reader, readerClose } = initializeReader())
3032
},
3133
)
@@ -38,7 +40,14 @@ export function createReaderWatch(filePath, { signal } = {}) {
3840
}
3941

4042
return Object.assign(
41-
function getReader() {
43+
async function getReader() {
44+
if (isWin) {
45+
try {
46+
await fs.promises.access(filePath, fs.constants.F_OK)
47+
} catch {
48+
;({ reader, readerClose } = initializeReader())
49+
}
50+
}
4251
return reader
4352
},
4453
{

test/reader-watch.test.js

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,14 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url))
1515
const FIXTURE1_PATH = path.join(__dirname, 'fixtures', 'demotiles-z2.smp')
1616
const FIXTURE2_PATH = path.join(__dirname, 'fixtures', 'osm-bright-z6.smp')
1717

18-
/** @param {import('node:test').TestContext} t */
1918
function tempDir() {
2019
return fs.mkdtempSync(path.join(tmpdir(), 'comapeo-map-server-'))
2120
}
2221

2322
test('createReaderWatch - valid smp file', async (t) => {
2423
const getReader = createReaderWatch(FIXTURE1_PATH)
2524
t.after(getReader.close)
26-
const reader = getReader()
25+
const reader = await getReader()
2726
const style = await reader.getStyle('/')
2827
assert(style, 'Style should be returned')
2928
const tile = await reader.getResource('s/1/0/0/0.mvt.gz')
@@ -41,7 +40,7 @@ test('createReaderWatch - file does not exist initially', async (t) => {
4140
await getReader.close()
4241
await rmDir(dir)
4342
})
44-
const reader1 = getReader()
43+
const reader1 = await getReader()
4544
// Attempting to read from non-existent file should throw
4645
await assert.rejects(
4746
async () => await reader1.getStyle(),
@@ -50,7 +49,7 @@ test('createReaderWatch - file does not exist initially', async (t) => {
5049
)
5150
fs.copyFileSync(FIXTURE1_PATH, nonExistentPath)
5251
await syncDir(dir) // Ensure copy is flushed and directory is synced
53-
const reader2 = getReader()
52+
const reader2 = await getReader()
5453
// Now the reader should point to the new file
5554
const style = await reader2.getStyle()
5655
assert(style, 'Style should be readable after file is created')
@@ -71,15 +70,15 @@ test('createReaderWatch - file is replaced with different file', async (t) => {
7170
})
7271

7372
// Read from initial file
74-
const reader1 = getReader()
73+
const reader1 = await getReader()
7574
const style1 = await reader1.getStyle()
7675
assert.equal(style1.name, 'MapLibre', 'Expected style name from fixture 1')
7776

7877
fs.copyFileSync(FIXTURE2_PATH, targetPath)
7978
await syncDir(dir)
8079

8180
// The reader should be recreated
82-
const reader2 = getReader()
81+
const reader2 = await getReader()
8382
const style2 = await reader2.getStyle()
8483
assert.equal(style2.name, 'OSM Bright', 'Expected style name from fixture 2')
8584
})
@@ -96,7 +95,7 @@ test('createReaderWatch - file is deleted', async (t) => {
9695
await rmDir(dir)
9796
})
9897

99-
const reader1 = getReader()
98+
const reader1 = await getReader()
10099
const style1 = await reader1.getStyle()
101100
assert.equal(
102101
style1.name,
@@ -108,7 +107,7 @@ test('createReaderWatch - file is deleted', async (t) => {
108107
fs.rmSync(targetPath, { force: true, maxRetries: 5 })
109108
await syncDir(dir)
110109

111-
const reader2 = getReader()
110+
const reader2 = await getReader()
112111
try {
113112
await reader2.getStyle()
114113
console.log('Style read succeeded unexpectedly after file deletion')
@@ -137,7 +136,7 @@ test('createReaderWatch - invalid file (non-smp file)', async (t) => {
137136
await rmDir(dir)
138137
})
139138

140-
const reader = getReader()
139+
const reader = await getReader()
141140
assert(reader, 'Reader instance should be returned even for invalid file')
142141

143142
// Attempting to read from invalid file should throw
@@ -149,7 +148,7 @@ test('createReaderWatch - invalid file (non-smp file)', async (t) => {
149148
fs.copyFileSync(FIXTURE1_PATH, invalidPath)
150149
await syncDir(dir)
151150

152-
const reader2 = getReader()
151+
const reader2 = await getReader()
153152
const style = await reader2.getStyle()
154153
assert.equal(
155154
style.name,
@@ -169,7 +168,7 @@ test('createReaderWatch - close() cleans up watcher', async (t) => {
169168
await rmDir(dir)
170169
})
171170

172-
const reader1 = getReader()
171+
const reader1 = await getReader()
173172
const style = await reader1.getStyle()
174173
assert.equal(style.name, 'MapLibre', 'Should be able to read before closing')
175174

@@ -180,7 +179,7 @@ test('createReaderWatch - close() cleans up watcher', async (t) => {
180179
fs.copyFileSync(FIXTURE2_PATH, targetPath)
181180
await syncDir(dir)
182181

183-
const reader2 = getReader()
182+
const reader2 = await getReader()
184183
// The reader should still be the old instance
185184
assert.strictEqual(
186185
reader1,
@@ -210,7 +209,7 @@ test('createReaderWatch - AbortSignal integration', async (t) => {
210209
await rmDir(dir)
211210
})
212211

213-
const reader = getReader()
212+
const reader = await getReader()
214213
const style = await reader.getStyle()
215214
assert(style, 'Should be able to read with AbortSignal')
216215

@@ -221,7 +220,7 @@ test('createReaderWatch - AbortSignal integration', async (t) => {
221220
await syncDir(dir)
222221

223222
// reader should still be same instance because watcher is closed
224-
const reader2 = getReader()
223+
const reader2 = await getReader()
225224
assert.strictEqual(
226225
reader,
227226
reader2,
@@ -247,7 +246,7 @@ test('createReaderWatch - watcher only recreates reader for target file changes'
247246

248247
const getReader = createReaderWatch(targetPath)
249248

250-
const reader1 = getReader()
249+
const reader1 = await getReader()
251250
t.after(async () => {
252251
await getReader.close()
253252
await rmDir(dir)
@@ -263,7 +262,7 @@ test('createReaderWatch - watcher only recreates reader for target file changes'
263262
await syncDir(dir)
264263

265264
// reader should be same instance (not changed because of file watcher)
266-
const reader2 = getReader()
265+
const reader2 = await getReader()
267266
assert.strictEqual(
268267
reader1,
269268
reader2,
@@ -274,8 +273,8 @@ test('createReaderWatch - watcher only recreates reader for target file changes'
274273
test('createReaderWatch - getReader returns current reader instance', async (t) => {
275274
const getReader = createReaderWatch(FIXTURE1_PATH)
276275
t.after(getReader.close)
277-
const reader1 = getReader()
278-
const reader2 = getReader()
276+
const reader1 = await getReader()
277+
const reader2 = await getReader()
279278

280279
// Before any file changes, should return the same instance
281280
assert.strictEqual(

0 commit comments

Comments
 (0)