@@ -146,37 +146,22 @@ <h2>Get note by ID</h2>
146146 return sdk ;
147147 }
148148
149- // List the latest notes across the whole contract. The contract's only
150- // indices are byOwnerUpdated / byOwnerCreated (both compound on $ownerId),
151- // so a true "newest across all owners" sort has no index to satisfy. We
152- // issue a bare query (no where, no orderBy) and re-sort client-side by
153- // $updatedAt desc. Same approach as listAllCards in dashmint-lite.
154- async function listRecent ( sdk , limit = DEFAULT_LIMIT ) {
155- const results = await sdk . documents . query ( {
156- dataContractId : CONTRACT_ID ,
157- documentTypeName : DOC_TYPE ,
158- limit,
159- } ) ;
160- return normalizeNotes ( results ) . sort (
161- ( a , b ) => ( b . updatedAt ?? 0 ) - ( a . updatedAt ?? 0 ) ,
162- ) ;
163- }
164-
165- // List notes owned by a single identity. The byOwnerUpdated index requires
166- // $ownerId to lead the orderBy, so we sort newest-first client-side.
167- // Mirrors listMyNotes in src/dash/queries.ts in the React app.
168- async function listByOwner ( sdk , ownerId , limit = DEFAULT_LIMIT ) {
169- const trimmed = ownerId . trim ( ) ;
170- if ( ! trimmed ) return [ ] ;
171- const results = await sdk . documents . query ( {
172- dataContractId : CONTRACT_ID ,
173- documentTypeName : DOC_TYPE ,
174- where : [ [ '$ownerId' , '==' , trimmed ] ] ,
175- orderBy : [ [ '$ownerId' , 'asc' ] , [ '$updatedAt' , 'asc' ] ] ,
176- limit,
177- } ) ;
149+ // List notes from the contract. With no ownerId, issues a bare query (no
150+ // where/orderBy) since the contract's only indices are byOwnerUpdated /
151+ // byOwnerCreated, both compound on $ownerId — there is no index that
152+ // satisfies "newest across all owners". Same approach as listAllCards in
153+ // dashmint-lite. With an ownerId, uses the byOwnerUpdated index. Result
154+ // is always sorted client-side newest-first by $updatedAt.
155+ async function listNotes ( sdk , ownerId , limit = DEFAULT_LIMIT ) {
156+ const trimmed = ownerId ?. trim ( ) ?? '' ;
157+ const query = { dataContractId : CONTRACT_ID , documentTypeName : DOC_TYPE , limit } ;
158+ if ( trimmed ) {
159+ query . where = [ [ '$ownerId' , '==' , trimmed ] ] ;
160+ query . orderBy = [ [ '$ownerId' , 'asc' ] , [ '$updatedAt' , 'asc' ] ] ;
161+ }
162+ const results = await sdk . documents . query ( query ) ;
178163 return normalizeNotes ( results ) . sort (
179- ( a , b ) => ( b . updatedAt ?? 0 ) - ( a . updatedAt ?? 0 ) ,
164+ ( a , b ) => ( b . updatedAtIso ?? '' ) . localeCompare ( a . updatedAtIso ?? '' ) ,
180165 ) ;
181166 }
182167
@@ -205,41 +190,31 @@ <h2>Get note by ID</h2>
205190 // Some result shapes wrap the document; .toJSON() unwraps it. Fallback to
206191 // treating `doc` itself as the data when toJSON isn't present.
207192 const data = ( doc && typeof doc . toJSON === 'function' ) ? doc . toJSON ( ) : doc ;
208- const createdAt = toTs ( data . $createdAt ) ;
209- const updatedAt = toTs ( data . $updatedAt ) ;
210- const revision = toRev ( data . $revision ?? doc ?. revision ) ;
211193 return {
212194 id : String ( id ?? data . $id ?? data . id ?? '' ) ,
213195 ownerId : data . $ownerId ? String ( data . $ownerId ) : null ,
214196 title : typeof data . title === 'string' ? data . title : null ,
215197 message : typeof data . message === 'string' ? data . message : '' ,
216- createdAt,
217- createdAtIso : createdAt ? new Date ( createdAt ) . toISOString ( ) : null ,
218- updatedAt,
219- updatedAtIso : updatedAt ? new Date ( updatedAt ) . toISOString ( ) : null ,
220- revision,
198+ createdAtIso : toIso ( data . $createdAt ) ,
199+ updatedAtIso : toIso ( data . $updatedAt ) ,
200+ revision : toNum ( data . $revision ?? doc ?. revision , 0 ) ,
221201 } ;
222202 }
223203
224- // $createdAt / $updatedAt arrive as number, bigint, or numeric string.
225- function toTs ( value ) {
204+ // $createdAt / $updatedAt / $revision arrive as number, bigint, or numeric string.
205+ function toNum ( value , fallback ) {
226206 if ( typeof value === 'number' && Number . isFinite ( value ) ) return value ;
227207 if ( typeof value === 'bigint' ) return Number ( value ) ;
228208 if ( typeof value === 'string' && value ) {
229209 const n = Number ( value ) ;
230- return Number . isFinite ( n ) ? n : null ;
210+ if ( Number . isFinite ( n ) ) return n ;
231211 }
232- return null ;
212+ return fallback ;
233213 }
234214
235- function toRev ( value ) {
236- if ( typeof value === 'number' && Number . isFinite ( value ) ) return value ;
237- if ( typeof value === 'bigint' ) return Number ( value ) ;
238- if ( typeof value === 'string' && value ) {
239- const n = Number ( value ) ;
240- return Number . isFinite ( n ) ? n : 0 ;
241- }
242- return 0 ;
215+ function toIso ( value ) {
216+ const n = toNum ( value , null ) ;
217+ return n != null ? new Date ( n ) . toISOString ( ) : null ;
243218 }
244219
245220 // ============================================================================
@@ -280,16 +255,10 @@ <h2>Get note by ID</h2>
280255
281256 // Truncate an id to head…tail for compact display while keeping the full
282257 // value on the element via data-id (for copy) and title (for hover).
283- function shortId ( id ) {
284- if ( ! id ) return '' ;
285- const s = String ( id ) ;
286- return s . length > 16 ? `${ s . slice ( 0 , 6 ) } …${ s . slice ( - 6 ) } ` : s ;
287- }
288-
289258 function copyIdSpan ( fullId ) {
290259 const span = document . createElement ( 'span' ) ;
291260 span . className = 'copy-id' ;
292- span . textContent = shortId ( fullId ) ;
261+ span . textContent = fullId . length > 16 ? ` ${ fullId . slice ( 0 , 6 ) } … ${ fullId . slice ( - 6 ) } ` : fullId ;
293262 span . dataset . id = fullId ;
294263 span . title = fullId ;
295264 return span ;
@@ -304,7 +273,7 @@ <h2>Get note by ID</h2>
304273 }
305274 // One-line muted footer: timestamp · rev (if >1) · doc-id [· owner]
306275 const footer = makeDiv ( 'footer' ) ;
307- const isEdited = n . updatedAt != null && n . createdAt != null && n . updatedAt !== n . createdAt ;
276+ const isEdited = n . updatedAtIso != null && n . createdAtIso != null && n . updatedAtIso !== n . createdAtIso ;
308277 const tsLabel = isEdited ? 'Updated' : 'Created' ;
309278 const tsValue = fmtDate ( isEdited ? n . updatedAtIso : n . createdAtIso ) ;
310279 if ( tsValue ) footer . append ( `${ tsLabel } ${ tsValue } ` ) ;
@@ -351,9 +320,7 @@ <h2>Get note by ID</h2>
351320 const owner = ownerInput . value . trim ( ) ;
352321 recentResultEl . replaceChildren ( statusLine ( 'Querying…' ) ) ;
353322 try {
354- const notes = owner
355- ? await listByOwner ( sdk , owner , DEFAULT_LIMIT )
356- : await listRecent ( sdk , DEFAULT_LIMIT ) ;
323+ const notes = await listNotes ( sdk , owner , DEFAULT_LIMIT ) ;
357324 if ( notes . length === 0 ) {
358325 const msg = owner
359326 ? `No notes found for owner "${ owner } ".`
0 commit comments