Skip to content

Commit 32b52a7

Browse files
committed
progress (reporting)
1 parent b92d822 commit 32b52a7

File tree

5 files changed

+67
-18
lines changed

5 files changed

+67
-18
lines changed

.claude/settings.local.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@
3030
"Bash(unset:*)",
3131
"Bash(LOG_LEVEL=debug ./trans link-finder)",
3232
"Bash(cat:*)",
33-
"Bash(LOG_LEVEL=trace ./trans:*)"
33+
"Bash(LOG_LEVEL=trace ./trans:*)",
34+
"Bash(\"http://localhost:3030/test/query?query=PREFIX%20bm%3A%20%3Chttp%3A%2F%2Fpurl.org%2Fstuff%2Fbm%2F%3E%0ASELECT%20%28COUNT%28%3Fbookmark%29%20AS%20%3Fcount%29%20FROM%20%3Chttp%3A%2F%2Fhyperdata.it%2Fcontent%3E%20WHERE%20%7B%20%3Fbookmark%20a%20bm%3ABookmark%20%7D\")"
3435
],
3536
"deny": []
3637
},

src/apps/link-finder/about.md

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,23 @@ If no entry exists for the bm:target, then this new one is created. Otherwise th
4040
bm:status "200"^^xsd:integer .
4141
```
4242

43-
--
44-
PREFIX : <http://purl.org/stuff/transmissions/>
43+
## Verification Query
44+
45+
Count bookmarks in the store:
46+
47+
```sparql
4548
PREFIX bm: <http://purl.org/stuff/bm/>
4649
47-
INSERT DATA {
48-
GRAPH <{{graph}}> {
49-
<http://purl.org/stuff/instance/eprxly1u> a bm:Bookmark ;
50-
bm:target <https://tensegrity.it/> ;
51-
bm:agent <http://purl.org/stuff/agent/transmissions> ;
52-
bm:created "2025-09-28" ;
53-
bm:title "Tensegrity" ;
54-
bm:status "404"^^xsd:integer .
55-
}
50+
SELECT (COUNT(?bookmark) AS ?count)
51+
FROM <http://hyperdata.it/content>
52+
WHERE {
53+
?bookmark a bm:Bookmark .
5654
}
55+
```
56+
57+
Or via curl:
58+
59+
```sh
60+
curl -s -H "Accept: text/plain" --user admin:admin123 \
61+
"http://localhost:3030/test/query?query=PREFIX%20bm%3A%20%3Chttp%3A%2F%2Fpurl.org%2Fstuff%2Fbm%2F%3E%0ASELECT%20%28COUNT%28%3Fbookmark%29%20AS%20%3Fcount%29%20FROM%20%3Chttp%3A%2F%2Fhyperdata.it%2Fcontent%3E%20WHERE%20%7B%20%3Fbookmark%20a%20bm%3ABookmark%20%7D"
62+
```

src/apps/link-finder/config.ttl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
# ns.trn.sourceFile
99

1010
:origin a :ConfigSet ;
11-
:sourceFile "test.md" .
12-
# :targetField "links" .
11+
:sourceFile "workflowy_2025-09-21.md" .
12+
# :sourceFile "test.md" .
1313

1414
:listField a :ConfigSet ;
1515
:remove "true" ;
@@ -20,6 +20,9 @@
2020
:pp1 :pre "currentItem.url" ;
2121
:post "url" .
2222

23+
:httpSettings a :ConfigSet ;
24+
:timeout "10000" .
25+
2326
:normalizeURL a :ConfigSet ;
2427
:inputField "resource.target" ;
2528
:outputField "resource.target" ;
@@ -63,7 +66,7 @@
6366

6467
:updateBookmark a :ConfigSet ;
6568
# :loglevel "debug" ;
66-
:delay "100" ;
69+
:delay "500" ;
6770
:dataBlock "resource" ;
6871
:templateFilename "data/update-bookmark.njk" ;
6972
:noCache "true" ; # always reload endpoints

src/processors/flow/ForEach.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ class ForEach extends SlowableProcessor {
9292
const reduced = current
9393

9494
logger.debug(` reduced.length = ${reduced.length}`)
95+
logger.log(`ForEach: Processing ${reduced.length} items`)
9596

9697
// logger.v(reduced)
9798

@@ -110,6 +111,9 @@ class ForEach extends SlowableProcessor {
110111
message = JSONUtils.remove(message, forEach)
111112
}
112113
message.done = false
114+
const totalItems = reduced.length
115+
const progressInterval = Math.max(1, Math.floor(totalItems / 20)) // Report every 5%
116+
113117
for (const item of reduced) {
114118

115119
if (limitString && ++counter > limit) continue
@@ -124,11 +128,19 @@ class ForEach extends SlowableProcessor {
124128
clonedMessage.foreach = undefined
125129

126130
logger.log(`ForEach: Emitting message for item: ${JSON.stringify(item)}`)
127-
clonedMessage.eachCounter = this.eachCounter++
131+
clonedMessage.eachCounter = this.eachCounter
132+
133+
// Progress logging
134+
if (this.eachCounter % progressInterval === 0 || this.eachCounter === totalItems - 1) {
135+
const percent = Math.round((this.eachCounter / totalItems) * 100)
136+
logger.log(`ForEach: Progress ${this.eachCounter + 1}/${totalItems} (${percent}%)`)
137+
}
138+
139+
this.eachCounter++
128140
this.emit('message', clonedMessage)
129141
}
130142
message.done = true
131-
logger.log('ForEach: all messages dispatched')
143+
logger.log(`ForEach: All ${totalItems} messages dispatched`)
132144

133145
this.emit('message', message)
134146
}

src/processors/http/HttpClient.js

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,18 @@ class HttpClient extends Processor {
8989
const method = super.getProperty(ns.trn.method, 'GET').toUpperCase()
9090
const headers = super.getProperty(ns.trn.headers, {})
9191
const body = super.getProperty(ns.trn.body, null)
92+
const timeout = super.getProperty(ns.trn.timeout, 30000) // Default 30s timeout
9293

9394
const options = { method, headers }
95+
96+
// Add timeout using AbortController
97+
if (timeout) {
98+
const controller = new AbortController()
99+
options.signal = controller.signal
100+
options.controller = controller
101+
options.timeout = parseInt(timeout)
102+
}
103+
94104
if (body && (method === 'POST' || method === 'PUT' || method === 'PATCH')) {
95105
options.body = typeof body === 'string' ? body : JSON.stringify(body)
96106
if (!headers['Content-Type']) {
@@ -107,7 +117,24 @@ class HttpClient extends Processor {
107117
* @returns {Promise<Response>}
108118
*/
109119
async _sendRequest(requestOptions) {
110-
const { url, ...options } = requestOptions
120+
const { url, timeout, controller, ...options } = requestOptions
121+
122+
// Handle timeout
123+
if (timeout && controller) {
124+
const timeoutId = setTimeout(() => {
125+
controller.abort()
126+
}, timeout)
127+
128+
try {
129+
const response = await fetch(url, options)
130+
clearTimeout(timeoutId)
131+
return response
132+
} catch (error) {
133+
clearTimeout(timeoutId)
134+
throw error
135+
}
136+
}
137+
111138
return fetch(url, options)
112139
}
113140

0 commit comments

Comments
 (0)