@seed-hypermedia/client 0.0.1 → 0.0.2
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/dist/auto-link.d.ts +61 -0
- package/dist/block-diff.d.ts +62 -0
- package/dist/blocks-to-markdown.d.ts +33 -0
- package/dist/change.d.ts +7 -0
- package/dist/{chunk-YUKHBJYL.mjs → chunk-PPK3SKPV.mjs} +253 -6
- package/dist/client.d.ts +1 -1
- package/dist/comment.d.ts +5 -0
- package/dist/contact.d.ts +16 -2
- package/dist/document-state.d.ts +23 -0
- package/dist/file-to-ipfs.d.ts +53 -0
- package/dist/grobid.d.ts +22 -0
- package/dist/hm-types.d.ts +2935 -202
- package/dist/hm-types.mjs +47 -1
- package/dist/index.d.ts +33 -13
- package/dist/index.mjs +2378 -64
- package/dist/markdown-to-blocks.d.ts +88 -0
- package/dist/pdf-to-blocks-embedded.d.ts +23 -0
- package/dist/pdf-to-blocks.d.ts +55 -0
- package/dist/ref.d.ts +2 -0
- package/dist/tei-to-blocks.d.ts +52 -0
- package/package.json +45 -17
- package/src/index.ts +74 -0
- package/LICENSE +0 -201
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-link child documents to their parent on first publish.
|
|
3
|
+
*
|
|
4
|
+
* When a document is created at a nested path (e.g. /docs/my-article), the
|
|
5
|
+
* parent document at /docs should contain an embed link pointing to the child.
|
|
6
|
+
* This module provides:
|
|
7
|
+
*
|
|
8
|
+
* - Pure decision logic: should a link be added?
|
|
9
|
+
* - Operation builder: what DocumentOperations to emit
|
|
10
|
+
* - Full I/O convenience: fetch parent, check, build ops, sign, publish
|
|
11
|
+
*/
|
|
12
|
+
import type { HMDocument, HMSigner, UnpackedHypermediaId } from './hm-types';
|
|
13
|
+
import type { SeedClient } from './client';
|
|
14
|
+
import type { DocumentOperation } from './change';
|
|
15
|
+
/**
|
|
16
|
+
* Check if a document contains a link/embed to a specific child document.
|
|
17
|
+
* Compares URLs ignoring version and latest flags.
|
|
18
|
+
*/
|
|
19
|
+
export declare function documentContainsLinkToChild(document: HMDocument, childId: UnpackedHypermediaId): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Check if a document has a self-referential Query block
|
|
22
|
+
* (a query to itself that would automatically include children).
|
|
23
|
+
*/
|
|
24
|
+
export declare function documentHasSelfQuery(document: HMDocument, documentId: UnpackedHypermediaId): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Determine whether a parent auto-link should be added on first publish.
|
|
27
|
+
* Returns true when the parent document should receive an embed link to the child.
|
|
28
|
+
*/
|
|
29
|
+
export declare function shouldAutoLinkParent(isPrivate: boolean, parentDocument: HMDocument | null, editableLocation: UnpackedHypermediaId, parentId: UnpackedHypermediaId): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Generate the DocumentOperations to append an Embed Card block to a parent document.
|
|
32
|
+
*
|
|
33
|
+
* The returned operations include a ReplaceBlock for the new embed block and a
|
|
34
|
+
* MoveBlocks that lists ALL root-level block IDs (existing + new) to ensure
|
|
35
|
+
* correct ordering. The CBOR MoveBlocks format with no `ref` positions blocks
|
|
36
|
+
* from the start, so we must re-specify the full ordering.
|
|
37
|
+
*/
|
|
38
|
+
export declare function createAutoLinkOps(parentDocument: HMDocument, childHmUrl: string, newBlockId: string): DocumentOperation[];
|
|
39
|
+
/** Options for the auto-link convenience function. */
|
|
40
|
+
export type AutoLinkChildToParentOptions = {
|
|
41
|
+
/** Seed API client. */
|
|
42
|
+
client: SeedClient;
|
|
43
|
+
/** Account UID of the document owner. */
|
|
44
|
+
account: string;
|
|
45
|
+
/** Full path of the child document (e.g. "/tests/benefits-of-cli"). */
|
|
46
|
+
path: string;
|
|
47
|
+
/** hm:// URL of the published child document (with version). */
|
|
48
|
+
childHmUrl: string;
|
|
49
|
+
/** Signer for the parent document change. */
|
|
50
|
+
signer: HMSigner;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Auto-link a newly published child document to its parent.
|
|
54
|
+
*
|
|
55
|
+
* Computes the parent path, fetches the parent document, decides whether a link
|
|
56
|
+
* is needed (using `shouldAutoLinkParent`), and if so publishes an Embed Card
|
|
57
|
+
* block to the parent document.
|
|
58
|
+
*
|
|
59
|
+
* Returns true if a link was added, false otherwise. Throws on network errors.
|
|
60
|
+
*/
|
|
61
|
+
export declare function autoLinkChildToParent(opts: AutoLinkChildToParentOptions): Promise<boolean>;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Block diffing utilities for document update.
|
|
3
|
+
*
|
|
4
|
+
* Computes minimal document operations by comparing existing document
|
|
5
|
+
* blocks with new blocks parsed from Markdown or JSON input.
|
|
6
|
+
*
|
|
7
|
+
* The primary flow trusts block IDs from the input: if an input block's
|
|
8
|
+
* ID exists in the old document, it's treated as an existing block and
|
|
9
|
+
* diffed for content changes. If the ID doesn't exist, the block is
|
|
10
|
+
* treated as new. Old blocks whose IDs don't appear in the new tree
|
|
11
|
+
* are deleted. This gives per-block granularity — a mix of known and
|
|
12
|
+
* unknown IDs is handled correctly.
|
|
13
|
+
*/
|
|
14
|
+
import type { DocumentOperation } from './change';
|
|
15
|
+
import type { HMBlockNode } from './hm-types';
|
|
16
|
+
import type { BlockNode } from './markdown-to-blocks';
|
|
17
|
+
export type APIBlockNode = {
|
|
18
|
+
block: APIBlock;
|
|
19
|
+
children: APIBlockNode[];
|
|
20
|
+
};
|
|
21
|
+
export type APIBlock = {
|
|
22
|
+
id: string;
|
|
23
|
+
type: string;
|
|
24
|
+
text: string;
|
|
25
|
+
link: string;
|
|
26
|
+
annotations: unknown[];
|
|
27
|
+
attributes: Record<string, unknown>;
|
|
28
|
+
revision?: string;
|
|
29
|
+
};
|
|
30
|
+
type BlocksMapItem = {
|
|
31
|
+
parent: string;
|
|
32
|
+
left: string;
|
|
33
|
+
block: APIBlock;
|
|
34
|
+
};
|
|
35
|
+
type BlocksMap = Record<string, BlocksMapItem>;
|
|
36
|
+
export declare function createBlocksMap(nodes: APIBlockNode[], parentId?: string): BlocksMap;
|
|
37
|
+
/**
|
|
38
|
+
* Walk old and new block trees in parallel. When the new block at
|
|
39
|
+
* position N has the same type as the old block at position N, reuse
|
|
40
|
+
* the old block's ID. Otherwise assign the new block's generated ID.
|
|
41
|
+
*
|
|
42
|
+
* Returns a new tree with IDs reassigned (does not mutate inputs).
|
|
43
|
+
*/
|
|
44
|
+
export declare function matchBlockIds(oldNodes: APIBlockNode[], newNodes: BlockNode[]): BlockNode[];
|
|
45
|
+
/**
|
|
46
|
+
* Compare the new block tree against the old blocks map and produce
|
|
47
|
+
* the minimal set of DocumentOperations:
|
|
48
|
+
*
|
|
49
|
+
* - ReplaceBlock for new or content-changed blocks
|
|
50
|
+
* - MoveBlocks for positioning (new blocks or position changes)
|
|
51
|
+
* - DeleteBlocks for blocks removed from the document
|
|
52
|
+
*/
|
|
53
|
+
export declare function computeReplaceOps(oldMap: BlocksMap, matchedTree: BlockNode[], parentId?: string): DocumentOperation[];
|
|
54
|
+
/**
|
|
55
|
+
* Convert an HMBlockNode tree (from JSON input or API response) into
|
|
56
|
+
* a BlockNode tree compatible with the diff pipeline.
|
|
57
|
+
*
|
|
58
|
+
* HMBlockNode nests childrenType/language inside `attributes`, while
|
|
59
|
+
* SeedBlock/BlockNode has them at the top level.
|
|
60
|
+
*/
|
|
61
|
+
export declare function hmBlockNodeToBlockNode(node: HMBlockNode): BlockNode;
|
|
62
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Seed block tree → Markdown formatter.
|
|
3
|
+
*
|
|
4
|
+
* Converts HMDocument/HMBlockNode trees to markdown with:
|
|
5
|
+
* - YAML frontmatter (always emitted, all HMMetadata fields)
|
|
6
|
+
* - Block IDs preserved as HTML comments (<!-- id:XXXXXXXX -->)
|
|
7
|
+
* - Inline annotations rendered as markdown formatting
|
|
8
|
+
*
|
|
9
|
+
* This module is purely synchronous and does NOT resolve embeds, mentions,
|
|
10
|
+
* or queries over the network. For resolved output, use the CLI's wrapper
|
|
11
|
+
* which adds a SeedClient-backed resolve layer on top.
|
|
12
|
+
*
|
|
13
|
+
* Round-trip compatible: output can be piped back through `parseMarkdown()`
|
|
14
|
+
* to recreate the same document with block IDs preserved.
|
|
15
|
+
*/
|
|
16
|
+
import type { HMDocument, HMMetadata } from './hm-types';
|
|
17
|
+
export type BlocksToMarkdownOptions = {
|
|
18
|
+
/** Format ipfs:// URLs as https gateway URLs. Default: true. */
|
|
19
|
+
ipfsGateway?: boolean;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Emit YAML frontmatter from HMMetadata.
|
|
23
|
+
* Only includes fields that have defined, non-empty values.
|
|
24
|
+
* System fields (authors, version, genesis, account) are NOT emitted.
|
|
25
|
+
*/
|
|
26
|
+
export declare function emitFrontmatter(metadata: HMMetadata): string;
|
|
27
|
+
/**
|
|
28
|
+
* Convert an HMDocument to markdown with frontmatter and block IDs.
|
|
29
|
+
*
|
|
30
|
+
* This is a synchronous, pure conversion. Embeds/queries are rendered
|
|
31
|
+
* as placeholder links (not resolved).
|
|
32
|
+
*/
|
|
33
|
+
export declare function blocksToMarkdown(doc: HMDocument, options?: BlocksToMarkdownOptions): string;
|
package/dist/change.d.ts
CHANGED
|
@@ -103,6 +103,11 @@ export declare function createDocumentChange(input: CreateDocumentChangeInput, s
|
|
|
103
103
|
bytes: Uint8Array;
|
|
104
104
|
cid: CID;
|
|
105
105
|
}>;
|
|
106
|
+
/**
|
|
107
|
+
* Map a proto ResourceVisibility enum value to the CBOR string used in Ref blobs.
|
|
108
|
+
* Returns "Private" for private documents, undefined otherwise (omitted from CBOR = public).
|
|
109
|
+
*/
|
|
110
|
+
export declare function visibilityToCbor(protoVisibility?: number): string | undefined;
|
|
106
111
|
export type SignDocumentChangeInput = {
|
|
107
112
|
/** Account UID (base58btc-encoded principal) */
|
|
108
113
|
account: string;
|
|
@@ -116,6 +121,8 @@ export type SignDocumentChangeInput = {
|
|
|
116
121
|
generation?: number | bigint;
|
|
117
122
|
/** Optional capability CID string */
|
|
118
123
|
capability?: string;
|
|
124
|
+
/** Proto ResourceVisibility enum value (0=unspecified, 1=public, 2=private) */
|
|
125
|
+
visibility?: number;
|
|
119
126
|
};
|
|
120
127
|
/**
|
|
121
128
|
* Sign a prepared change and create a version ref, returning blobs ready for publishing.
|
|
@@ -221,6 +221,7 @@ var HMDocumentMetadataSchema = z.object({
|
|
|
221
221
|
siteUrl: z.string().optional(),
|
|
222
222
|
layout: z.union([z.literal("Seed/Experimental/Newspaper"), z.literal("")]).optional(),
|
|
223
223
|
displayPublishTime: z.string().optional(),
|
|
224
|
+
displayAuthor: z.string().optional(),
|
|
224
225
|
seedExperimentalLogo: z.string().optional(),
|
|
225
226
|
seedExperimentalHomeOrder: z.union([z.literal("UpdatedFirst"), z.literal("CreatedFirst")]).optional(),
|
|
226
227
|
showOutline: z.boolean().optional(),
|
|
@@ -339,6 +340,10 @@ var HMAccountNotFoundSchema = z.object({
|
|
|
339
340
|
uid: z.string()
|
|
340
341
|
});
|
|
341
342
|
var HMAccountResultSchema = z.discriminatedUnion("type", [HMAccountPayloadSchema, HMAccountNotFoundSchema]);
|
|
343
|
+
var HMSiteMemberSchema = z.object({
|
|
344
|
+
account: unpackedHmIdSchema,
|
|
345
|
+
role: z.enum(["owner", "writer", "member"])
|
|
346
|
+
});
|
|
342
347
|
var HMAccountsMetadataSchema = z.record(
|
|
343
348
|
z.string(),
|
|
344
349
|
// account uid
|
|
@@ -356,7 +361,8 @@ var HMQuerySortSchema = z.object({
|
|
|
356
361
|
z.literal("Title"),
|
|
357
362
|
z.literal("CreateTime"),
|
|
358
363
|
z.literal("UpdateTime"),
|
|
359
|
-
z.literal("DisplayTime")
|
|
364
|
+
z.literal("DisplayTime"),
|
|
365
|
+
z.literal("ActivityTime")
|
|
360
366
|
])
|
|
361
367
|
});
|
|
362
368
|
var HMQuerySchema = z.object({
|
|
@@ -475,13 +481,19 @@ var HMResolvedResourceSchema = z.discriminatedUnion("type", [
|
|
|
475
481
|
HMResourceCommentSchema,
|
|
476
482
|
HMResourceTombstoneSchema
|
|
477
483
|
]);
|
|
484
|
+
var HMContactSubscribeSchema = z.object({
|
|
485
|
+
site: z.boolean().optional(),
|
|
486
|
+
profile: z.boolean().optional()
|
|
487
|
+
});
|
|
478
488
|
var HMContactRecordSchema = z.object({
|
|
479
489
|
id: z.string(),
|
|
480
490
|
subject: z.string(),
|
|
481
491
|
name: z.string(),
|
|
482
492
|
account: z.string(),
|
|
493
|
+
signer: z.string(),
|
|
483
494
|
createTime: HMTimestampSchema.optional(),
|
|
484
|
-
updateTime: HMTimestampSchema.optional()
|
|
495
|
+
updateTime: HMTimestampSchema.optional(),
|
|
496
|
+
subscribe: HMContactSubscribeSchema.optional()
|
|
485
497
|
});
|
|
486
498
|
var HMAccountContactsRequestSchema = z.object({
|
|
487
499
|
key: z.literal("AccountContacts"),
|
|
@@ -489,6 +501,122 @@ var HMAccountContactsRequestSchema = z.object({
|
|
|
489
501
|
// account UID
|
|
490
502
|
output: z.array(HMContactRecordSchema)
|
|
491
503
|
});
|
|
504
|
+
var HMCommentDraftSchema = z.object({
|
|
505
|
+
blocks: z.array(HMBlockNodeSchema),
|
|
506
|
+
targetDocId: z.string().optional(),
|
|
507
|
+
replyCommentId: z.string().optional(),
|
|
508
|
+
quotingBlockId: z.string().optional(),
|
|
509
|
+
context: z.enum(["accessory", "feed", "document-content"]).optional(),
|
|
510
|
+
lastUpdateTime: z.number().optional()
|
|
511
|
+
});
|
|
512
|
+
var HMListedCommentDraftSchema = z.object({
|
|
513
|
+
id: z.string(),
|
|
514
|
+
targetDocId: z.string(),
|
|
515
|
+
replyCommentId: z.string().optional(),
|
|
516
|
+
quotingBlockId: z.string().optional(),
|
|
517
|
+
context: z.enum(["accessory", "feed", "document-content"]).optional(),
|
|
518
|
+
lastUpdateTime: z.number()
|
|
519
|
+
});
|
|
520
|
+
var HMHostConfigSchema = z.object({
|
|
521
|
+
peerId: z.string(),
|
|
522
|
+
registeredAccountUid: z.string(),
|
|
523
|
+
protocolId: z.string(),
|
|
524
|
+
addrs: z.array(z.string()),
|
|
525
|
+
hostname: z.string(),
|
|
526
|
+
isGateway: z.boolean()
|
|
527
|
+
});
|
|
528
|
+
var HMContactSchema = z.object({
|
|
529
|
+
metadata: HMDocumentMetadataSchema,
|
|
530
|
+
contacts: z.array(HMContactRecordSchema).optional(),
|
|
531
|
+
subjectContacts: z.array(HMContactRecordSchema).optional()
|
|
532
|
+
});
|
|
533
|
+
var HMContactItemSchema = z.object({
|
|
534
|
+
id: unpackedHmIdSchema,
|
|
535
|
+
metadata: HMDocumentMetadataSchema.optional()
|
|
536
|
+
});
|
|
537
|
+
var HMCapabilitySchema = z.object({
|
|
538
|
+
id: z.string(),
|
|
539
|
+
accountUid: z.string(),
|
|
540
|
+
role: HMRoleSchema,
|
|
541
|
+
capabilityId: z.string().optional(),
|
|
542
|
+
grantId: unpackedHmIdSchema,
|
|
543
|
+
label: z.string().optional(),
|
|
544
|
+
createTime: HMTimestampSchema
|
|
545
|
+
});
|
|
546
|
+
var siteDiscoverRequestSchema = z.object({
|
|
547
|
+
uid: z.string(),
|
|
548
|
+
path: z.array(z.string()),
|
|
549
|
+
version: z.string().optional(),
|
|
550
|
+
media: z.boolean().optional()
|
|
551
|
+
});
|
|
552
|
+
var HMPeerConnectionRequestSchema = z.object({
|
|
553
|
+
a: z.array(z.string()),
|
|
554
|
+
// addrs
|
|
555
|
+
d: z.string()
|
|
556
|
+
// peer/device ID
|
|
557
|
+
});
|
|
558
|
+
var ParsedFragmentSchema = BlockRangeSchema.extend({
|
|
559
|
+
blockId: z.string()
|
|
560
|
+
});
|
|
561
|
+
var HMCitationCommentSourceSchema = z.object({
|
|
562
|
+
type: z.literal("c"),
|
|
563
|
+
id: unpackedHmIdSchema,
|
|
564
|
+
author: z.string().optional(),
|
|
565
|
+
time: HMTimestampSchema.optional()
|
|
566
|
+
});
|
|
567
|
+
var HMCitationDocumentSourceSchema = z.object({
|
|
568
|
+
type: z.literal("d"),
|
|
569
|
+
id: unpackedHmIdSchema,
|
|
570
|
+
author: z.string().optional(),
|
|
571
|
+
time: HMTimestampSchema.optional()
|
|
572
|
+
});
|
|
573
|
+
var HMCitationSchema = z.object({
|
|
574
|
+
source: z.discriminatedUnion("type", [HMCitationCommentSourceSchema, HMCitationDocumentSourceSchema]),
|
|
575
|
+
isExactVersion: z.boolean(),
|
|
576
|
+
targetFragment: ParsedFragmentSchema.nullable(),
|
|
577
|
+
targetId: unpackedHmIdSchema
|
|
578
|
+
});
|
|
579
|
+
var DeviceLinkSessionSchema = z.object({
|
|
580
|
+
accountId: z.string(),
|
|
581
|
+
secretToken: z.string(),
|
|
582
|
+
addrInfo: z.object({
|
|
583
|
+
peerId: z.string(),
|
|
584
|
+
addrs: z.array(z.string())
|
|
585
|
+
})
|
|
586
|
+
});
|
|
587
|
+
var HMNavigationItemSchema = z.object({
|
|
588
|
+
type: z.literal("Link"),
|
|
589
|
+
id: z.string(),
|
|
590
|
+
text: z.string(),
|
|
591
|
+
link: z.string()
|
|
592
|
+
});
|
|
593
|
+
var HMDraftContentSchema = z.object({
|
|
594
|
+
content: z.array(z.any()),
|
|
595
|
+
// EditorBlock validation is handled elsewhere
|
|
596
|
+
deps: z.array(z.string().min(1)).default([]),
|
|
597
|
+
navigation: z.array(HMNavigationItemSchema).optional()
|
|
598
|
+
});
|
|
599
|
+
var HMDraftMetaBaseSchema = z.object({
|
|
600
|
+
id: z.string(),
|
|
601
|
+
locationUid: z.string().optional(),
|
|
602
|
+
locationPath: z.array(z.string()).optional(),
|
|
603
|
+
editUid: z.string().optional(),
|
|
604
|
+
editPath: z.array(z.string()).optional(),
|
|
605
|
+
metadata: HMDocumentMetadataSchema,
|
|
606
|
+
visibility: HMResourceVisibilitySchema.optional().default("PUBLIC")
|
|
607
|
+
});
|
|
608
|
+
var draftLocationRefinement = (data) => data.editUid || data.locationUid;
|
|
609
|
+
var HMDraftMetaSchema = HMDraftMetaBaseSchema.refine(draftLocationRefinement, {
|
|
610
|
+
message: "Either editUid or locationUid must be provided"
|
|
611
|
+
});
|
|
612
|
+
var HMListedDraftSchema = HMDraftMetaBaseSchema.extend({
|
|
613
|
+
lastUpdateTime: z.number()
|
|
614
|
+
}).refine(draftLocationRefinement, {
|
|
615
|
+
message: "Either editUid or locationUid must be provided"
|
|
616
|
+
});
|
|
617
|
+
var HMListedDraftReadSchema = HMDraftMetaBaseSchema.extend({
|
|
618
|
+
lastUpdateTime: z.number()
|
|
619
|
+
});
|
|
492
620
|
var HMSubjectContactsRequestSchema = z.object({
|
|
493
621
|
key: z.literal("SubjectContacts"),
|
|
494
622
|
input: z.string(),
|
|
@@ -521,7 +649,8 @@ var HMSearchInputSchema = z.object({
|
|
|
521
649
|
includeBody: z.boolean().optional(),
|
|
522
650
|
contextSize: z.number().optional(),
|
|
523
651
|
perspectiveAccountUid: z.string().optional(),
|
|
524
|
-
searchType: z.number().optional()
|
|
652
|
+
searchType: z.number().optional(),
|
|
653
|
+
pageSize: z.number().optional()
|
|
525
654
|
});
|
|
526
655
|
var HMSearchResultItemSchema = z.object({
|
|
527
656
|
id: unpackedHmIdSchema,
|
|
@@ -529,7 +658,7 @@ var HMSearchResultItemSchema = z.object({
|
|
|
529
658
|
title: z.string(),
|
|
530
659
|
icon: z.string(),
|
|
531
660
|
parentNames: z.array(z.string()),
|
|
532
|
-
versionTime: z.
|
|
661
|
+
versionTime: z.string().optional(),
|
|
533
662
|
searchQuery: z.string(),
|
|
534
663
|
type: z.enum(["document", "contact"])
|
|
535
664
|
});
|
|
@@ -706,6 +835,7 @@ var HMInteractionSummaryOutputSchema = z.object({
|
|
|
706
835
|
comments: z.number(),
|
|
707
836
|
changes: z.number(),
|
|
708
837
|
children: z.number(),
|
|
838
|
+
authorUids: z.array(z.string()).default([]),
|
|
709
839
|
blocks: z.record(
|
|
710
840
|
z.string(),
|
|
711
841
|
z.object({
|
|
@@ -872,7 +1002,7 @@ function getHMQueryString({
|
|
|
872
1002
|
if (version) {
|
|
873
1003
|
query.v = version;
|
|
874
1004
|
}
|
|
875
|
-
if (latest) {
|
|
1005
|
+
if (latest && version) {
|
|
876
1006
|
query.l = null;
|
|
877
1007
|
}
|
|
878
1008
|
if (panel) {
|
|
@@ -905,6 +1035,100 @@ function entityQueryPathToHmIdPath(path) {
|
|
|
905
1035
|
if (path === "/") return [];
|
|
906
1036
|
return path.split("/").filter(Boolean);
|
|
907
1037
|
}
|
|
1038
|
+
function parseCustomURL(url) {
|
|
1039
|
+
if (!url) return null;
|
|
1040
|
+
const [scheme, rest] = url.split("://");
|
|
1041
|
+
if (!rest) return null;
|
|
1042
|
+
const [pathAndQuery, fragment = null] = rest.split("#");
|
|
1043
|
+
const [path, queryString] = (pathAndQuery == null ? void 0 : pathAndQuery.split("?")) || [];
|
|
1044
|
+
const query = new URLSearchParams(queryString);
|
|
1045
|
+
const queryObject = Object.fromEntries(query.entries());
|
|
1046
|
+
return {
|
|
1047
|
+
scheme: scheme || null,
|
|
1048
|
+
path: (path == null ? void 0 : path.split("/")) || [],
|
|
1049
|
+
query: queryObject,
|
|
1050
|
+
fragment
|
|
1051
|
+
};
|
|
1052
|
+
}
|
|
1053
|
+
function parseFragment(input) {
|
|
1054
|
+
if (!input) return null;
|
|
1055
|
+
const regex = /^([^\+\[]+)((\+)|\[(\d+)\:(\d+)\])?$/;
|
|
1056
|
+
const match = input.match(regex);
|
|
1057
|
+
if (match) {
|
|
1058
|
+
const blockId = match[1] || "";
|
|
1059
|
+
const expanded = match[3];
|
|
1060
|
+
const rangeStart = match[4];
|
|
1061
|
+
const rangeEnd = match[5];
|
|
1062
|
+
if (expanded === "+") {
|
|
1063
|
+
return { blockId, expanded: true };
|
|
1064
|
+
} else if (typeof rangeStart !== "undefined" && typeof rangeEnd !== "undefined") {
|
|
1065
|
+
return { blockId, start: parseInt(rangeStart), end: parseInt(rangeEnd) };
|
|
1066
|
+
} else {
|
|
1067
|
+
return { blockId, expanded: false };
|
|
1068
|
+
}
|
|
1069
|
+
} else {
|
|
1070
|
+
return { blockId: input, expanded: false };
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
var STATIC_HM_PATHS = /* @__PURE__ */ new Set(["download", "connect", "register", "device-link", "profile", "contact"]);
|
|
1074
|
+
function unpackHmId(hypermediaId) {
|
|
1075
|
+
if (!hypermediaId) return null;
|
|
1076
|
+
const parsed = parseCustomURL(hypermediaId);
|
|
1077
|
+
if (!parsed) return null;
|
|
1078
|
+
let uid;
|
|
1079
|
+
let path;
|
|
1080
|
+
let hostname = null;
|
|
1081
|
+
if (parsed.scheme === "https" || parsed.scheme === "http") {
|
|
1082
|
+
if (parsed.path[1] !== "hm") return null;
|
|
1083
|
+
hostname = parsed.path[0];
|
|
1084
|
+
uid = parsed.path[2];
|
|
1085
|
+
if (uid && STATIC_HM_PATHS.has(uid)) return null;
|
|
1086
|
+
path = parsed.path.slice(3);
|
|
1087
|
+
} else if (parsed.scheme === HYPERMEDIA_SCHEME || parsed.scheme === "hm") {
|
|
1088
|
+
uid = parsed.path[0];
|
|
1089
|
+
path = parsed.path.slice(1);
|
|
1090
|
+
} else {
|
|
1091
|
+
return null;
|
|
1092
|
+
}
|
|
1093
|
+
const version = parsed.query.v || null;
|
|
1094
|
+
const fragment = parseFragment(parsed.fragment);
|
|
1095
|
+
const hasBlockRef = !!(fragment == null ? void 0 : fragment.blockId);
|
|
1096
|
+
const latest = hasBlockRef ? false : parsed.query.l === null || parsed.query.l === "" || !version;
|
|
1097
|
+
let blockRange = null;
|
|
1098
|
+
if (fragment) {
|
|
1099
|
+
if ("start" in fragment) {
|
|
1100
|
+
blockRange = { start: fragment.start, end: fragment.end };
|
|
1101
|
+
} else if ("expanded" in fragment) {
|
|
1102
|
+
blockRange = { expanded: fragment.expanded };
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
return {
|
|
1106
|
+
id: packBaseId(uid || "", path),
|
|
1107
|
+
uid: uid || "",
|
|
1108
|
+
path: path || null,
|
|
1109
|
+
version,
|
|
1110
|
+
blockRef: fragment ? fragment.blockId : null,
|
|
1111
|
+
blockRange,
|
|
1112
|
+
hostname: hostname || null,
|
|
1113
|
+
latest,
|
|
1114
|
+
scheme: parsed.scheme
|
|
1115
|
+
};
|
|
1116
|
+
}
|
|
1117
|
+
function codePointLength(entry) {
|
|
1118
|
+
let count = 0;
|
|
1119
|
+
if (!entry) return 0;
|
|
1120
|
+
for (let i = 0; i < entry.length; i++) {
|
|
1121
|
+
count++;
|
|
1122
|
+
if (isSurrogate(entry, i)) {
|
|
1123
|
+
i++;
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
return count;
|
|
1127
|
+
}
|
|
1128
|
+
function isSurrogate(s, i) {
|
|
1129
|
+
const code = s.charCodeAt(i);
|
|
1130
|
+
return 55296 <= code && code <= 56319;
|
|
1131
|
+
}
|
|
908
1132
|
|
|
909
1133
|
export {
|
|
910
1134
|
BlockRangeSchema,
|
|
@@ -954,6 +1178,7 @@ export {
|
|
|
954
1178
|
HMAccountPayloadSchema,
|
|
955
1179
|
HMAccountNotFoundSchema,
|
|
956
1180
|
HMAccountResultSchema,
|
|
1181
|
+
HMSiteMemberSchema,
|
|
957
1182
|
HMAccountsMetadataSchema,
|
|
958
1183
|
HMQueryInclusionSchema,
|
|
959
1184
|
HMQuerySortSchema,
|
|
@@ -975,8 +1200,25 @@ export {
|
|
|
975
1200
|
HMResourceErrorSchema,
|
|
976
1201
|
HMResourceSchema,
|
|
977
1202
|
HMResolvedResourceSchema,
|
|
1203
|
+
HMContactSubscribeSchema,
|
|
978
1204
|
HMContactRecordSchema,
|
|
979
1205
|
HMAccountContactsRequestSchema,
|
|
1206
|
+
HMCommentDraftSchema,
|
|
1207
|
+
HMListedCommentDraftSchema,
|
|
1208
|
+
HMHostConfigSchema,
|
|
1209
|
+
HMContactSchema,
|
|
1210
|
+
HMContactItemSchema,
|
|
1211
|
+
HMCapabilitySchema,
|
|
1212
|
+
siteDiscoverRequestSchema,
|
|
1213
|
+
HMPeerConnectionRequestSchema,
|
|
1214
|
+
ParsedFragmentSchema,
|
|
1215
|
+
HMCitationSchema,
|
|
1216
|
+
DeviceLinkSessionSchema,
|
|
1217
|
+
HMNavigationItemSchema,
|
|
1218
|
+
HMDraftContentSchema,
|
|
1219
|
+
HMDraftMetaSchema,
|
|
1220
|
+
HMListedDraftSchema,
|
|
1221
|
+
HMListedDraftReadSchema,
|
|
980
1222
|
HMSubjectContactsRequestSchema,
|
|
981
1223
|
HMResourceRequestSchema,
|
|
982
1224
|
HMResourceMetadataRequestSchema,
|
|
@@ -1040,5 +1282,10 @@ export {
|
|
|
1040
1282
|
getHMQueryString,
|
|
1041
1283
|
serializeBlockRange,
|
|
1042
1284
|
hmIdPathToEntityQueryPath,
|
|
1043
|
-
entityQueryPathToHmIdPath
|
|
1285
|
+
entityQueryPathToHmIdPath,
|
|
1286
|
+
parseCustomURL,
|
|
1287
|
+
parseFragment,
|
|
1288
|
+
unpackHmId,
|
|
1289
|
+
codePointLength,
|
|
1290
|
+
isSurrogate
|
|
1044
1291
|
};
|
package/dist/client.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import type
|
|
2
|
+
import { type HMPrepareDocumentChangeInput, type HMRequest, type HMSigner } from './hm-types';
|
|
3
3
|
/**
|
|
4
4
|
* Deserializes a URL query string using a Zod schema.
|
|
5
5
|
* If the query contains only a __value key, returns the primitive value directly.
|
package/dist/comment.d.ts
CHANGED
|
@@ -40,4 +40,9 @@ export type DeleteCommentInput = {
|
|
|
40
40
|
visibility?: 'Private' | '';
|
|
41
41
|
};
|
|
42
42
|
export declare function deleteComment(input: DeleteCommentInput, signer: HMSigner): Promise<HMPublishBlobsInput>;
|
|
43
|
+
/**
|
|
44
|
+
* Compute the record ID ("authority/tsid") from raw CBOR-encoded comment blob bytes.
|
|
45
|
+
* The TSID is a 10-byte base58btc value: 6 bytes ms timestamp + 4 bytes SHA256 prefix.
|
|
46
|
+
*/
|
|
47
|
+
export declare function commentRecordIdFromBlob(blobData: Uint8Array): Promise<string>;
|
|
43
48
|
export {};
|
package/dist/contact.d.ts
CHANGED
|
@@ -1,21 +1,35 @@
|
|
|
1
1
|
import type { HMPublishBlobsInput, HMSigner } from './hm-types';
|
|
2
|
+
export type ContactSubscribe = {
|
|
3
|
+
site?: boolean;
|
|
4
|
+
profile?: boolean;
|
|
5
|
+
};
|
|
2
6
|
export type CreateContactInput = {
|
|
3
7
|
/** The subject account UID (base58btc-encoded principal) */
|
|
4
8
|
subjectUid: string;
|
|
9
|
+
/** The account UID (base58btc-encoded principal) */
|
|
10
|
+
accountUid?: string;
|
|
5
11
|
/** The display name for the contact */
|
|
6
|
-
name
|
|
12
|
+
name?: string;
|
|
13
|
+
/** The subscribe information for the contact */
|
|
14
|
+
subscribe?: ContactSubscribe;
|
|
7
15
|
};
|
|
8
16
|
export type UpdateContactInput = {
|
|
9
17
|
/** The contact record ID in format "authority/tsid" */
|
|
10
18
|
contactId: string;
|
|
11
19
|
/** The subject account UID */
|
|
12
20
|
subjectUid: string;
|
|
21
|
+
/** The account UID (base58btc-encoded principal) */
|
|
22
|
+
accountUid?: string;
|
|
13
23
|
/** The updated display name */
|
|
14
|
-
name
|
|
24
|
+
name?: string;
|
|
25
|
+
/** The subscribe information for the contact */
|
|
26
|
+
subscribe?: ContactSubscribe;
|
|
15
27
|
};
|
|
16
28
|
export type DeleteContactInput = {
|
|
17
29
|
/** The contact record ID in format "authority/tsid" */
|
|
18
30
|
contactId: string;
|
|
31
|
+
/** The account UID (base58btc-encoded principal) */
|
|
32
|
+
accountUid?: string;
|
|
19
33
|
};
|
|
20
34
|
export type CreateContactResult = HMPublishBlobsInput & {
|
|
21
35
|
/** The record ID in format "authority/tsid" */
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves document state (genesis, heads, depth) from the ListChanges API.
|
|
3
|
+
*
|
|
4
|
+
* Depth is needed to construct valid Change blobs but is not directly
|
|
5
|
+
* exposed by the read API. We compute it by walking the change DAG:
|
|
6
|
+
* genesis has depth 0, each subsequent change has depth = max(dep depths) + 1.
|
|
7
|
+
*/
|
|
8
|
+
import type { SeedClient } from './client';
|
|
9
|
+
/** The resolved state of a document's change DAG. */
|
|
10
|
+
export type DocumentState = {
|
|
11
|
+
/** CID of the genesis change blob. */
|
|
12
|
+
genesis: string;
|
|
13
|
+
/** CIDs of the current head changes (not depended on by any other change). */
|
|
14
|
+
heads: string[];
|
|
15
|
+
/** Maximum depth among head changes. */
|
|
16
|
+
headDepth: number;
|
|
17
|
+
/** Dot-separated head CIDs (version string). */
|
|
18
|
+
version: string;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Resolves the current document state including head depth.
|
|
22
|
+
*/
|
|
23
|
+
export declare function resolveDocumentState(client: SeedClient, targetId: string): Promise<DocumentState>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared IPFS file chunking utilities.
|
|
3
|
+
*
|
|
4
|
+
* Chunks binary data into UnixFS IPFS blocks using a MemoryBlockstore.
|
|
5
|
+
* Used by both the CLI (file:// link resolution) and the web app
|
|
6
|
+
* (comment attachment uploads) so the logic is not duplicated.
|
|
7
|
+
*/
|
|
8
|
+
import type { HMBlockNode } from './hm-types';
|
|
9
|
+
export type CollectedBlob = {
|
|
10
|
+
cid: string;
|
|
11
|
+
data: Uint8Array;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Chunk a single piece of binary data into UnixFS IPFS blocks.
|
|
15
|
+
*
|
|
16
|
+
* Returns the root CID and all constituent IPFS blobs (DAG blocks)
|
|
17
|
+
* that should be published alongside the document/comment.
|
|
18
|
+
*/
|
|
19
|
+
export declare function fileToIpfsBlobs(data: Uint8Array): Promise<{
|
|
20
|
+
cid: string;
|
|
21
|
+
blobs: CollectedBlob[];
|
|
22
|
+
}>;
|
|
23
|
+
/**
|
|
24
|
+
* Chunk multiple binary attachments into IPFS blocks using a shared blockstore.
|
|
25
|
+
*
|
|
26
|
+
* Returns the root CIDs (one per input) and all collected IPFS blobs.
|
|
27
|
+
* This is the multi-file equivalent of `fileToIpfsBlobs`, suitable for
|
|
28
|
+
* comment editors that upload several images at once.
|
|
29
|
+
*/
|
|
30
|
+
export declare function filesToIpfsBlobs(binaries: Uint8Array[]): Promise<{
|
|
31
|
+
resultCIDs: string[];
|
|
32
|
+
blobs: CollectedBlob[];
|
|
33
|
+
}>;
|
|
34
|
+
/**
|
|
35
|
+
* Resolve all file:// links in a block tree.
|
|
36
|
+
*
|
|
37
|
+
* Walks the tree, finds blocks whose `link` field starts with `file://`,
|
|
38
|
+
* reads the data via the provided `readFile` callback, chunks with UnixFS,
|
|
39
|
+
* and replaces the link with `ipfs://ROOT_CID`.
|
|
40
|
+
*
|
|
41
|
+
* The `readFile` callback allows this to work in both Node.js (fs.readFileSync)
|
|
42
|
+
* and browser environments without importing `fs` directly.
|
|
43
|
+
*
|
|
44
|
+
* @returns The modified block tree and all collected IPFS blobs.
|
|
45
|
+
*/
|
|
46
|
+
export declare function resolveFileLinksInBlocks(nodes: HMBlockNode[], readFile: (path: string) => Uint8Array | Promise<Uint8Array>): Promise<{
|
|
47
|
+
nodes: HMBlockNode[];
|
|
48
|
+
blobs: CollectedBlob[];
|
|
49
|
+
}>;
|
|
50
|
+
/**
|
|
51
|
+
* Check whether any block in the tree has a file:// link.
|
|
52
|
+
*/
|
|
53
|
+
export declare function hasFileLinks(nodes: HMBlockNode[]): boolean;
|
package/dist/grobid.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GROBID HTTP client — sends PDFs to a GROBID server for full-text extraction.
|
|
3
|
+
*
|
|
4
|
+
* Expects a running GROBID instance (e.g. via Docker):
|
|
5
|
+
* docker run --rm -p 8070:8070 grobid/grobid:0.8.2-full
|
|
6
|
+
*/
|
|
7
|
+
export declare const DEFAULT_GROBID_URL = "http://localhost:8070";
|
|
8
|
+
export interface GrobidOptions {
|
|
9
|
+
/** Base URL of the GROBID server (default: http://localhost:8070) */
|
|
10
|
+
grobidUrl?: string;
|
|
11
|
+
/** Request TEI coordinates for specific element types */
|
|
12
|
+
teiCoordinates?: string[];
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Check whether a GROBID server is reachable at the given URL.
|
|
16
|
+
* Returns true if the server responds within the timeout, false otherwise.
|
|
17
|
+
*/
|
|
18
|
+
export declare function isGrobidAvailable(grobidUrl?: string, timeoutMs?: number): Promise<boolean>;
|
|
19
|
+
/**
|
|
20
|
+
* Send a PDF to GROBID's processFulltextDocument endpoint and return TEI XML.
|
|
21
|
+
*/
|
|
22
|
+
export declare function processFulltextDocument(pdfBuffer: ArrayBuffer | Buffer, options?: GrobidOptions): Promise<string>;
|