polen 0.11.0-next.17 → 0.11.0-next.18
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/build/api/builder/ssg/generate.d.ts.map +1 -1
- package/build/api/builder/ssg/generate.js +5 -5
- package/build/api/builder/ssg/generate.js.map +1 -1
- package/build/api/builder/ssg/page-generator.worker.js +13 -3
- package/build/api/builder/ssg/page-generator.worker.js.map +1 -1
- package/build/api/config/input.d.ts +88 -3
- package/build/api/config/input.d.ts.map +1 -1
- package/build/api/config/normalized.d.ts +92 -7
- package/build/api/config/normalized.d.ts.map +1 -1
- package/build/api/config/normalized.js +11 -3
- package/build/api/config/normalized.js.map +1 -1
- package/build/api/config-template/template.js +2 -2
- package/build/api/config-template/template.js.map +1 -1
- package/build/api/content/sidebar.d.ts.map +1 -1
- package/build/api/content/sidebar.js +2 -1
- package/build/api/content/sidebar.js.map +1 -1
- package/build/api/examples/config.d.ts +366 -3
- package/build/api/examples/config.d.ts.map +1 -1
- package/build/api/examples/config.js +25 -3
- package/build/api/examples/config.js.map +1 -1
- package/build/api/examples/diagnostic/diagnostic.d.ts +1 -1
- package/build/api/examples/diagnostic/validation-error.d.ts +3 -2
- package/build/api/examples/diagnostic/validation-error.d.ts.map +1 -1
- package/build/api/examples/diagnostic/validation-error.js +9 -3
- package/build/api/examples/diagnostic/validation-error.js.map +1 -1
- package/build/api/examples/diagnostic/validator.d.ts.map +1 -1
- package/build/api/examples/diagnostic/validator.js +115 -68
- package/build/api/examples/diagnostic/validator.js.map +1 -1
- package/build/api/examples/filter.d.ts.map +1 -1
- package/build/api/examples/filter.js +9 -6
- package/build/api/examples/filter.js.map +1 -1
- package/build/api/examples/scanner.d.ts.map +1 -1
- package/build/api/examples/scanner.js +89 -103
- package/build/api/examples/scanner.js.map +1 -1
- package/build/api/examples/type-usage-indexer.d.ts.map +1 -1
- package/build/api/examples/type-usage-indexer.js +17 -30
- package/build/api/examples/type-usage-indexer.js.map +1 -1
- package/build/api/iso/schema/routing.d.ts.map +1 -1
- package/build/api/iso/schema/routing.js +8 -8
- package/build/api/iso/schema/routing.js.map +1 -1
- package/build/api/iso/schema/validation.d.ts.map +1 -1
- package/build/api/iso/schema/validation.js +3 -2
- package/build/api/iso/schema/validation.js.map +1 -1
- package/build/api/schema/input-sources/directory.js +2 -2
- package/build/api/schema/input-sources/directory.js.map +1 -1
- package/build/api/schema/input-sources/versioned-directory.d.ts.map +1 -1
- package/build/api/schema/input-sources/versioned-directory.js +3 -3
- package/build/api/schema/input-sources/versioned-directory.js.map +1 -1
- package/build/api/schema/load.d.ts.map +1 -1
- package/build/api/schema/load.js +1 -1
- package/build/api/schema/load.js.map +1 -1
- package/build/lib/catalog/catalog.d.ts +43 -3
- package/build/lib/catalog/catalog.d.ts.map +1 -1
- package/build/lib/catalog/catalog.js +67 -5
- package/build/lib/catalog/catalog.js.map +1 -1
- package/build/lib/catalog/versioned.d.ts +11 -1
- package/build/lib/catalog/versioned.d.ts.map +1 -1
- package/build/lib/catalog/versioned.js +23 -5
- package/build/lib/catalog/versioned.js.map +1 -1
- package/build/lib/document/document.d.ts +55 -5
- package/build/lib/document/document.d.ts.map +1 -1
- package/build/lib/document/document.js +96 -2
- package/build/lib/document/document.js.map +1 -1
- package/build/lib/document/versioned.d.ts +2 -2
- package/build/lib/document/versioned.d.ts.map +1 -1
- package/build/lib/document/versioned.js +7 -7
- package/build/lib/document/versioned.js.map +1 -1
- package/build/lib/lifecycles/lifecycles.d.ts +5 -4
- package/build/lib/lifecycles/lifecycles.d.ts.map +1 -1
- package/build/lib/lifecycles/lifecycles.js +14 -12
- package/build/lib/lifecycles/lifecycles.js.map +1 -1
- package/build/lib/version-coverage/$$.d.ts +2 -0
- package/build/lib/version-coverage/$$.d.ts.map +1 -0
- package/build/lib/version-coverage/$$.js +2 -0
- package/build/lib/version-coverage/$$.js.map +1 -0
- package/build/lib/version-coverage/$.d.ts.map +1 -0
- package/build/lib/version-coverage/$.js.map +1 -0
- package/build/lib/{version-selection/version-selection.d.ts → version-coverage/version-coverage.d.ts} +1 -1
- package/build/lib/version-coverage/version-coverage.d.ts.map +1 -0
- package/build/lib/{version-selection/version-selection.js → version-coverage/version-coverage.js} +2 -2
- package/build/lib/version-coverage/version-coverage.js.map +1 -0
- package/build/template/components/GraphQLDocument.d.ts +1 -1
- package/build/template/components/GraphQLDocument.d.ts.map +1 -1
- package/build/template/components/GraphQLDocument.js +10 -39
- package/build/template/components/GraphQLDocument.js.map +1 -1
- package/build/template/components/GraphQLInteractive/lib/parser.d.ts +28 -0
- package/build/template/components/GraphQLInteractive/lib/parser.d.ts.map +1 -1
- package/build/template/components/GraphQLInteractive/lib/parser.js +60 -27
- package/build/template/components/GraphQLInteractive/lib/parser.js.map +1 -1
- package/build/template/components/VersionCoveragePicker.d.ts +1 -1
- package/build/template/components/VersionCoveragePicker.d.ts.map +1 -1
- package/build/template/components/VersionCoveragePicker.js +4 -6
- package/build/template/components/VersionCoveragePicker.js.map +1 -1
- package/build/template/components/home/QuickStart.d.ts.map +1 -1
- package/build/template/components/home/QuickStart.js +8 -4
- package/build/template/components/home/QuickStart.js.map +1 -1
- package/build/template/hooks/use-highlighted.d.ts.map +1 -1
- package/build/template/hooks/use-highlighted.js +19 -13
- package/build/template/hooks/use-highlighted.js.map +1 -1
- package/build/template/lib/fetch-text.d.ts +18 -0
- package/build/template/lib/fetch-text.d.ts.map +1 -1
- package/build/template/lib/fetch-text.js +32 -4
- package/build/template/lib/fetch-text.js.map +1 -1
- package/build/template/routes/examples/name.d.ts.map +1 -1
- package/build/template/routes/examples/name.js +4 -2
- package/build/template/routes/examples/name.js.map +1 -1
- package/build/template/stores/toast.d.ts.map +1 -1
- package/build/template/stores/toast.js +5 -3
- package/build/template/stores/toast.js.map +1 -1
- package/package.json +7 -7
- package/src/api/builder/ssg/generate.ts +10 -5
- package/src/api/builder/ssg/page-generator.worker.ts +18 -3
- package/src/api/config/normalized.ts +12 -3
- package/src/api/config-template/template.ts +2 -2
- package/src/api/content/sidebar.ts +3 -3
- package/src/api/examples/config.test.ts +10 -0
- package/src/api/examples/config.ts +33 -4
- package/src/api/examples/diagnostic/validation-error.ts +9 -3
- package/src/api/examples/diagnostic/validator.test.ts +30 -0
- package/src/api/examples/diagnostic/validator.ts +148 -103
- package/src/api/examples/filter.ts +9 -6
- package/src/api/examples/scanner.ts +136 -117
- package/src/api/examples/type-usage-indexer.ts +24 -36
- package/src/api/iso/schema/routing.ts +10 -10
- package/src/api/iso/schema/validation.ts +3 -2
- package/src/api/schema/input-sources/directory.ts +2 -2
- package/src/api/schema/input-sources/versioned-directory.ts +5 -7
- package/src/api/schema/load.ts +1 -1
- package/src/lib/catalog/catalog.ts +89 -6
- package/src/lib/catalog/versioned.ts +26 -5
- package/src/lib/document/document.ts +135 -2
- package/src/lib/document/versioned.ts +8 -8
- package/src/lib/lifecycles/lifecycles.ts +32 -27
- package/src/lib/version-coverage/$$.ts +1 -0
- package/src/lib/{version-selection/version-selection.ts → version-coverage/version-coverage.ts} +1 -1
- package/src/template/components/GraphQLDocument.tsx +11 -69
- package/src/template/components/GraphQLInteractive/lib/parser.ts +81 -29
- package/src/template/components/VersionCoveragePicker.tsx +4 -5
- package/src/template/components/home/QuickStart.tsx +16 -7
- package/src/template/hooks/use-highlighted.ts +31 -19
- package/src/template/lib/fetch-text.ts +45 -4
- package/src/template/routes/examples/name.tsx +4 -2
- package/src/template/stores/toast.ts +6 -3
- package/build/lib/graph/$$.d.ts +0 -2
- package/build/lib/graph/$$.d.ts.map +0 -1
- package/build/lib/graph/$$.js +0 -2
- package/build/lib/graph/$$.js.map +0 -1
- package/build/lib/graph/$.d.ts +0 -2
- package/build/lib/graph/$.d.ts.map +0 -1
- package/build/lib/graph/$.js +0 -2
- package/build/lib/graph/$.js.map +0 -1
- package/build/lib/graph/graph.d.ts +0 -127
- package/build/lib/graph/graph.d.ts.map +0 -1
- package/build/lib/graph/graph.js +0 -152
- package/build/lib/graph/graph.js.map +0 -1
- package/build/lib/mask/$$.d.ts +0 -3
- package/build/lib/mask/$$.d.ts.map +0 -1
- package/build/lib/mask/$$.js +0 -3
- package/build/lib/mask/$$.js.map +0 -1
- package/build/lib/mask/$.d.ts +0 -2
- package/build/lib/mask/$.d.ts.map +0 -1
- package/build/lib/mask/$.js +0 -2
- package/build/lib/mask/$.js.map +0 -1
- package/build/lib/mask/apply.d.ts +0 -86
- package/build/lib/mask/apply.d.ts.map +0 -1
- package/build/lib/mask/apply.js +0 -86
- package/build/lib/mask/apply.js.map +0 -1
- package/build/lib/mask/mask.d.ts +0 -124
- package/build/lib/mask/mask.d.ts.map +0 -1
- package/build/lib/mask/mask.js +0 -137
- package/build/lib/mask/mask.js.map +0 -1
- package/build/lib/mask/mask.test-d.d.ts +0 -2
- package/build/lib/mask/mask.test-d.d.ts.map +0 -1
- package/build/lib/mask/mask.test-d.js +0 -102
- package/build/lib/mask/mask.test-d.js.map +0 -1
- package/build/lib/version-selection/$$.d.ts +0 -2
- package/build/lib/version-selection/$$.d.ts.map +0 -1
- package/build/lib/version-selection/$$.js +0 -2
- package/build/lib/version-selection/$$.js.map +0 -1
- package/build/lib/version-selection/$.d.ts.map +0 -1
- package/build/lib/version-selection/$.js.map +0 -1
- package/build/lib/version-selection/version-selection.d.ts.map +0 -1
- package/build/lib/version-selection/version-selection.js.map +0 -1
- package/src/lib/graph/$$.ts +0 -1
- package/src/lib/graph/$.ts +0 -1
- package/src/lib/graph/graph.ts +0 -197
- package/src/lib/mask/$$.ts +0 -2
- package/src/lib/mask/$.test.ts +0 -226
- package/src/lib/mask/$.ts +0 -1
- package/src/lib/mask/apply.ts +0 -134
- package/src/lib/mask/mask.test-d.ts +0 -156
- package/src/lib/mask/mask.ts +0 -244
- package/src/lib/version-selection/$$.ts +0 -1
- /package/build/lib/{version-selection → version-coverage}/$.d.ts +0 -0
- /package/build/lib/{version-selection → version-coverage}/$.js +0 -0
- /package/src/lib/{version-selection → version-coverage}/$.ts +0 -0
@@ -7,6 +7,7 @@
|
|
7
7
|
|
8
8
|
import { Api } from '#api/iso'
|
9
9
|
import type { CodeAnnotation } from 'codehike/code'
|
10
|
+
import { Either } from 'effect'
|
10
11
|
import {
|
11
12
|
getNamedType,
|
12
13
|
type GraphQLArgument,
|
@@ -504,41 +505,65 @@ class SemanticContext {
|
|
504
505
|
}
|
505
506
|
|
506
507
|
/**
|
507
|
-
*
|
508
|
+
* Error types for GraphQL parsing
|
509
|
+
*/
|
510
|
+
export type ParseError =
|
511
|
+
| { readonly _tag: 'InvalidInput'; readonly message: string }
|
512
|
+
| { readonly _tag: 'DocumentTooLarge'; readonly maxSize: number; readonly actualSize: number }
|
513
|
+
| { readonly _tag: 'TreeSitterError'; readonly message: string }
|
514
|
+
| { readonly _tag: 'ParserInitError'; readonly message: string }
|
515
|
+
|
516
|
+
const makeParseError = {
|
517
|
+
invalidInput: (message: string): ParseError => ({ _tag: 'InvalidInput', message }),
|
518
|
+
documentTooLarge: (maxSize: number, actualSize: number): ParseError => ({
|
519
|
+
_tag: 'DocumentTooLarge',
|
520
|
+
maxSize,
|
521
|
+
actualSize,
|
522
|
+
}),
|
523
|
+
treeSitterError: (message: string): ParseError => ({ _tag: 'TreeSitterError', message }),
|
524
|
+
parserInitError: (message: string): ParseError => ({ _tag: 'ParserInitError', message }),
|
525
|
+
}
|
526
|
+
|
527
|
+
/**
|
528
|
+
* Parse GraphQL code into interactive tokens with semantic information (Either version)
|
508
529
|
*
|
509
530
|
* @param code - The raw GraphQL code to parse
|
510
531
|
* @param annotations - CodeHike annotations that might affect rendering
|
511
532
|
* @param schema - Optional GraphQL schema for semantic analysis
|
512
|
-
* @returns
|
533
|
+
* @returns Either with array of tokens on right or ParseError on left
|
513
534
|
*/
|
514
|
-
export async function
|
535
|
+
export async function parseGraphQLWithTreeSitterEither(
|
515
536
|
code: string,
|
516
537
|
annotations: CodeAnnotation[] = [],
|
517
538
|
schema?: GraphQLSchema,
|
518
|
-
): Promise<GraphQLToken[]
|
539
|
+
): Promise<Either.Either<GraphQLToken[], ParseError>> {
|
519
540
|
// Validate input
|
520
541
|
if (!code || typeof code !== 'string') {
|
521
|
-
|
542
|
+
return Either.left(makeParseError.invalidInput('Invalid GraphQL code: code must be a non-empty string'))
|
522
543
|
}
|
523
544
|
|
524
545
|
// Prevent parsing extremely large documents that could cause performance issues
|
525
|
-
|
526
|
-
|
546
|
+
const maxSize = 100_000
|
547
|
+
if (code.length > maxSize) {
|
548
|
+
return Either.left(makeParseError.documentTooLarge(maxSize, code.length))
|
527
549
|
}
|
528
550
|
|
529
551
|
// Step 1: Parse with tree-sitter
|
530
|
-
|
552
|
+
let parser: WebTreeSitter.Parser
|
553
|
+
try {
|
554
|
+
parser = await getParser()
|
555
|
+
} catch (error) {
|
556
|
+
return Either.left(makeParseError.parserInitError(
|
557
|
+
error instanceof Error ? error.message : 'Failed to initialize parser',
|
558
|
+
))
|
559
|
+
}
|
560
|
+
|
531
561
|
const tree = parser.parse(code)
|
532
562
|
|
533
563
|
if (!tree) {
|
534
|
-
|
564
|
+
return Either.left(makeParseError.treeSitterError('Tree-sitter failed to parse GraphQL code'))
|
535
565
|
}
|
536
566
|
|
537
|
-
// Check if tree-sitter found syntax errors (disabled for now as it may be too strict)
|
538
|
-
// if (tree.rootNode.hasError) {
|
539
|
-
// throw new Error('GraphQL syntax error detected by tree-sitter parser')
|
540
|
-
// }
|
541
|
-
|
542
567
|
try {
|
543
568
|
// Step 2: Walk tree and attach semantics
|
544
569
|
const tokens = collectTokensWithSemantics(tree, code, schema, annotations)
|
@@ -546,26 +571,53 @@ export async function parseGraphQLWithTreeSitter(
|
|
546
571
|
// Step 3: Add error hint tokens after invalid fields
|
547
572
|
const tokensWithHints = addErrorHintTokens(tokens, code, annotations)
|
548
573
|
|
549
|
-
return tokensWithHints
|
574
|
+
return Either.right(tokensWithHints)
|
575
|
+
} catch (error) {
|
576
|
+
return Either.left(makeParseError.treeSitterError(
|
577
|
+
error instanceof Error ? error.message : 'Failed to process tokens',
|
578
|
+
))
|
550
579
|
} finally {
|
551
|
-
//
|
552
|
-
//
|
553
|
-
// Tree-sitter creates native WASM objects that must be explicitly freed to prevent memory leaks.
|
554
|
-
// The tree object holds references to parsed nodes and internal parser state that won't be
|
555
|
-
// garbage collected automatically by JavaScript.
|
556
|
-
//
|
557
|
-
// Critical cleanup points:
|
558
|
-
// 1. Always call tree.delete() in a finally block to ensure cleanup even on errors
|
559
|
-
// 2. Do not access tree or any of its nodes after calling delete()
|
560
|
-
// 3. The parser instance is cached globally and reused across multiple parsing calls
|
561
|
-
//
|
562
|
-
// Memory safety: Once tree.delete() is called, all WebTreeSitter.Node references become invalid.
|
563
|
-
// Our tokens hold references to these nodes, but only use their text and position properties
|
564
|
-
// which are copied during token creation, so the nodes can be safely deleted.
|
580
|
+
// Tree-sitter Resource Lifecycle Management
|
565
581
|
tree.delete()
|
566
582
|
}
|
567
583
|
}
|
568
584
|
|
585
|
+
/**
|
586
|
+
* Parse GraphQL code into interactive tokens with semantic information
|
587
|
+
*
|
588
|
+
* @param code - The raw GraphQL code to parse
|
589
|
+
* @param annotations - CodeHike annotations that might affect rendering
|
590
|
+
* @param schema - Optional GraphQL schema for semantic analysis
|
591
|
+
* @returns Array of tokens representing the parsed code
|
592
|
+
* @deprecated Use parseGraphQLWithTreeSitterEither for better error handling
|
593
|
+
*/
|
594
|
+
export async function parseGraphQLWithTreeSitter(
|
595
|
+
code: string,
|
596
|
+
annotations: CodeAnnotation[] = [],
|
597
|
+
schema?: GraphQLSchema,
|
598
|
+
): Promise<GraphQLToken[]> {
|
599
|
+
const result = await parseGraphQLWithTreeSitterEither(code, annotations, schema)
|
600
|
+
|
601
|
+
if (Either.isLeft(result)) {
|
602
|
+
const error = result.left
|
603
|
+
switch (error._tag) {
|
604
|
+
case 'InvalidInput':
|
605
|
+
throw new Error(error.message)
|
606
|
+
case 'DocumentTooLarge':
|
607
|
+
throw new Error(`GraphQL document too large: maximum ${error.maxSize} characters allowed`)
|
608
|
+
case 'TreeSitterError':
|
609
|
+
case 'ParserInitError':
|
610
|
+
throw new Error(error.message)
|
611
|
+
default: {
|
612
|
+
const exhaustiveCheck: never = error
|
613
|
+
throw new Error(`Unhandled parse error: ${JSON.stringify(exhaustiveCheck)}`)
|
614
|
+
}
|
615
|
+
}
|
616
|
+
}
|
617
|
+
|
618
|
+
return result.right
|
619
|
+
}
|
620
|
+
|
569
621
|
/**
|
570
622
|
* Get or create the tree-sitter parser instance
|
571
623
|
*/
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { Catalog } from '#lib/catalog/$'
|
2
2
|
import { Document } from '#lib/document/$'
|
3
|
-
import { VersionCoverage } from '#lib/version-
|
3
|
+
import { VersionCoverage } from '#lib/version-coverage'
|
4
4
|
import { Select } from '@radix-ui/themes'
|
5
5
|
import { HashMap } from 'effect'
|
6
6
|
import type { FC } from 'react'
|
@@ -30,12 +30,11 @@ export const VersionCoveragePicker: FC<Props> = ({
|
|
30
30
|
<Select.Root
|
31
31
|
value={VersionCoverage.toLabel(current)}
|
32
32
|
onValueChange={(label) => {
|
33
|
-
// Find
|
33
|
+
// Find the full version coverage by label and pass it entirely
|
34
34
|
const selection = options.find(s => VersionCoverage.toLabel(s) === label)
|
35
35
|
if (selection) {
|
36
|
-
|
37
|
-
|
38
|
-
if (version) onChange(version)
|
36
|
+
// Pass the entire VersionCoverage, not just the first version
|
37
|
+
onChange(selection)
|
39
38
|
}
|
40
39
|
}}
|
41
40
|
>
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import { Box, Card, Heading, Section, Tabs, Text } from '@radix-ui/themes'
|
2
2
|
import { highlight } from 'codehike/code'
|
3
|
+
import { Effect } from 'effect'
|
3
4
|
import * as React from 'react'
|
4
5
|
import { CodeBlock } from '../CodeBlock.js'
|
5
6
|
|
@@ -73,14 +74,22 @@ export const QuickStartSection: React.FC<Props> = ({ examples = defaultExamples
|
|
73
74
|
|
74
75
|
React.useEffect(() => {
|
75
76
|
const highlightExamples = async () => {
|
76
|
-
const highlighted = await
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
77
|
+
const highlighted = await Effect.runPromise(
|
78
|
+
Effect.all(
|
79
|
+
examples.map((example) =>
|
80
|
+
Effect.tryPromise({
|
81
|
+
try: async () => ({
|
82
|
+
label: example.label,
|
83
|
+
codeblock: await highlight(
|
84
|
+
{ value: example.code, lang: example.language, meta: '' },
|
85
|
+
{ theme: 'github-light' },
|
86
|
+
),
|
87
|
+
}),
|
88
|
+
catch: (error) => new Error(`Failed to highlight ${example.label}: ${error}`),
|
89
|
+
})
|
82
90
|
),
|
83
|
-
|
91
|
+
{ concurrency: 'unbounded' },
|
92
|
+
),
|
84
93
|
)
|
85
94
|
setHighlightedExamples(highlighted)
|
86
95
|
}
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import type { HighlightedCode } from 'codehike/code'
|
2
2
|
import { highlight } from 'codehike/code'
|
3
|
+
import { Duration, Effect } from 'effect'
|
3
4
|
import * as React from 'react'
|
4
5
|
|
5
6
|
/**
|
@@ -29,26 +30,37 @@ export const useHighlighted = (
|
|
29
30
|
const [highlightedCode, setHighlightedCode] = React.useState<HighlightedCode | null>(null)
|
30
31
|
|
31
32
|
React.useEffect(() => {
|
32
|
-
const
|
33
|
-
// Add a timeout to detect if highlight is hanging
|
34
|
-
const timeoutPromise = new Promise((_, reject) => {
|
35
|
-
setTimeout(() => reject(new Error('Highlight timeout after 5 seconds')), 5000)
|
36
|
-
})
|
37
|
-
|
38
|
-
const highlightPromise = highlight(
|
39
|
-
{
|
40
|
-
value: content,
|
41
|
-
lang: config.lang,
|
42
|
-
meta: metaString,
|
43
|
-
},
|
44
|
-
{
|
45
|
-
theme: 'github-light',
|
46
|
-
},
|
47
|
-
)
|
33
|
+
const HIGHLIGHT_TIMEOUT = Duration.seconds(5)
|
48
34
|
|
49
|
-
|
50
|
-
|
51
|
-
|
35
|
+
const highlightContent = async () => {
|
36
|
+
try {
|
37
|
+
const highlighted = await Effect.runPromise(
|
38
|
+
Effect.tryPromise({
|
39
|
+
try: () =>
|
40
|
+
highlight(
|
41
|
+
{
|
42
|
+
value: content,
|
43
|
+
lang: config.lang,
|
44
|
+
meta: metaString,
|
45
|
+
},
|
46
|
+
{
|
47
|
+
theme: 'github-light',
|
48
|
+
},
|
49
|
+
),
|
50
|
+
catch: (error) => new Error(`Highlight failed: ${error}`),
|
51
|
+
}).pipe(
|
52
|
+
Effect.timeout(HIGHLIGHT_TIMEOUT),
|
53
|
+
Effect.catchTag(
|
54
|
+
'TimeoutException',
|
55
|
+
() => Effect.fail(new Error(`Highlight timeout after ${Duration.toSeconds(HIGHLIGHT_TIMEOUT)} seconds`)),
|
56
|
+
),
|
57
|
+
),
|
58
|
+
)
|
59
|
+
setHighlightedCode(highlighted)
|
60
|
+
} catch (error) {
|
61
|
+
console.error('Failed to highlight code:', error)
|
62
|
+
setHighlightedCode(null)
|
63
|
+
}
|
52
64
|
}
|
53
65
|
highlightContent()
|
54
66
|
}, [content, config.lang, config.interactive])
|
@@ -1,13 +1,54 @@
|
|
1
|
+
import { Either } from 'effect'
|
2
|
+
|
3
|
+
/**
|
4
|
+
* Error type for fetch failures
|
5
|
+
*/
|
6
|
+
export interface FetchError {
|
7
|
+
readonly _tag: 'FetchError'
|
8
|
+
readonly url: string
|
9
|
+
readonly status: number
|
10
|
+
readonly statusText: string
|
11
|
+
readonly message: string
|
12
|
+
}
|
13
|
+
|
14
|
+
const makeFetchError = (url: string, status: number, statusText: string): FetchError => ({
|
15
|
+
_tag: 'FetchError',
|
16
|
+
url,
|
17
|
+
status,
|
18
|
+
statusText,
|
19
|
+
message: `Failed to fetch: ${url} (${status} ${statusText})`,
|
20
|
+
})
|
21
|
+
|
1
22
|
/**
|
2
23
|
* Fetch text content from a URL
|
3
24
|
* @param url - The URL to fetch from
|
25
|
+
* @returns Either with text content on right or FetchError on left
|
26
|
+
*/
|
27
|
+
export const fetchTextEither = async (url: string): Promise<Either.Either<string, FetchError>> => {
|
28
|
+
try {
|
29
|
+
const response = await fetch(url)
|
30
|
+
if (!response.ok) {
|
31
|
+
return Either.left(makeFetchError(url, response.status, response.statusText))
|
32
|
+
}
|
33
|
+
const text = await response.text()
|
34
|
+
return Either.right(text)
|
35
|
+
} catch (error) {
|
36
|
+
// Network errors or other exceptions
|
37
|
+
return Either.left(makeFetchError(url, 0, 'Network Error'))
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
/**
|
42
|
+
* Fetch text content from a URL (legacy throwing version)
|
43
|
+
* @param url - The URL to fetch from
|
4
44
|
* @returns Promise that resolves to the text content
|
5
45
|
* @throws Error if the request fails
|
46
|
+
* @deprecated Use fetchTextEither for better error handling
|
6
47
|
*/
|
7
48
|
export const fetchText = async (url: string): Promise<string> => {
|
8
|
-
const
|
9
|
-
if (
|
10
|
-
throw new Error(
|
49
|
+
const result = await fetchTextEither(url)
|
50
|
+
if (Either.isLeft(result)) {
|
51
|
+
throw new Error(result.left.message)
|
11
52
|
}
|
12
|
-
return
|
53
|
+
return result.right
|
13
54
|
}
|
@@ -4,6 +4,7 @@ import { useLoaderData } from '#lib/react-router-effect/use-loader-data'
|
|
4
4
|
import { Version } from '#lib/version/$'
|
5
5
|
import { Heading } from '@radix-ui/themes'
|
6
6
|
import { Str } from '@wollybeard/kit'
|
7
|
+
import { Array, Option } from 'effect'
|
7
8
|
import { useSearchParams } from 'react-router'
|
8
9
|
import { examplesCatalog } from 'virtual:polen/project/examples'
|
9
10
|
import { schemasCatalog } from 'virtual:polen/project/schemas'
|
@@ -23,10 +24,11 @@ export const nameLoader = async ({ params }: any) => {
|
|
23
24
|
}
|
24
25
|
|
25
26
|
// Check if the example exists
|
26
|
-
const
|
27
|
-
if (
|
27
|
+
const exampleOption = Array.findFirst(examplesCatalog.examples, (e) => e.name === name)
|
28
|
+
if (Option.isNone(exampleOption)) {
|
28
29
|
throw new Response('Not Found', { status: 404 })
|
29
30
|
}
|
31
|
+
const example = exampleOption.value
|
30
32
|
|
31
33
|
return example
|
32
34
|
}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { Schema as S } from 'effect'
|
1
|
+
import { Duration, Schema as S } from 'effect'
|
2
2
|
import { proxy } from 'valtio'
|
3
3
|
|
4
4
|
// ============================================================================
|
@@ -68,8 +68,10 @@ export const initialState: State = {
|
|
68
68
|
toasts: [],
|
69
69
|
}
|
70
70
|
|
71
|
+
const DEFAULT_TOAST_DURATION = Duration.seconds(5)
|
72
|
+
|
71
73
|
const toastDefaults = {
|
72
|
-
duration:
|
74
|
+
duration: Duration.toMillis(DEFAULT_TOAST_DURATION),
|
73
75
|
actions: [],
|
74
76
|
} satisfies Partial<Toast>
|
75
77
|
|
@@ -96,7 +98,8 @@ export const store = proxy({
|
|
96
98
|
|
97
99
|
// Auto-remove after duration (default 5 seconds). Set duration to 0 to disable auto-dismiss
|
98
100
|
if (toast.duration !== 0) {
|
99
|
-
|
101
|
+
const durationMs = toast.duration || toastDefaults.duration
|
102
|
+
setTimeout(() => store.remove(id), durationMs)
|
100
103
|
}
|
101
104
|
|
102
105
|
return id
|
package/build/lib/graph/$$.d.ts
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"$$.d.ts","sourceRoot":"","sources":["../../../src/lib/graph/$$.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA"}
|
package/build/lib/graph/$$.js
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"$$.js","sourceRoot":"","sources":["../../../src/lib/graph/$$.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA"}
|
package/build/lib/graph/$.d.ts
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"$.d.ts","sourceRoot":"","sources":["../../../src/lib/graph/$.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,SAAS,CAAA"}
|
package/build/lib/graph/$.js
DELETED
package/build/lib/graph/$.js.map
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"$.js","sourceRoot":"","sources":["../../../src/lib/graph/$.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,SAAS,CAAA"}
|
@@ -1,127 +0,0 @@
|
|
1
|
-
import { S } from '#lib/kit-temp/effect';
|
2
|
-
/**
|
3
|
-
* Dependency graph for tracking relationships between nodes
|
4
|
-
* Used to efficiently handle dependencies in various contexts
|
5
|
-
*/
|
6
|
-
export declare const DependencyGraph: S.Struct<{
|
7
|
-
/**
|
8
|
-
* Map from parent ID to array of child IDs (parent depends on children)
|
9
|
-
*/
|
10
|
-
dependencies: S.Record$<typeof S.String, S.Array$<typeof S.String>>;
|
11
|
-
/**
|
12
|
-
* Map from child ID to array of parent IDs (child is depended on by parents)
|
13
|
-
*/
|
14
|
-
dependents: S.Record$<typeof S.String, S.Array$<typeof S.String>>;
|
15
|
-
}>;
|
16
|
-
export type DependencyGraph = typeof DependencyGraph.Type;
|
17
|
-
export declare const make: (props: {
|
18
|
-
readonly dependencies: {
|
19
|
-
readonly [x: string]: readonly string[];
|
20
|
-
};
|
21
|
-
readonly dependents: {
|
22
|
-
readonly [x: string]: readonly string[];
|
23
|
-
};
|
24
|
-
}, options?: S.MakeOptions) => {
|
25
|
-
readonly dependencies: {
|
26
|
-
readonly [x: string]: readonly string[];
|
27
|
-
};
|
28
|
-
readonly dependents: {
|
29
|
-
readonly [x: string]: readonly string[];
|
30
|
-
};
|
31
|
-
};
|
32
|
-
/**
|
33
|
-
* Create an empty dependency graph
|
34
|
-
*/
|
35
|
-
export declare const create: () => DependencyGraph;
|
36
|
-
/**
|
37
|
-
* Add a dependency relationship (immutable)
|
38
|
-
* @param graph - The dependency graph
|
39
|
-
* @param parent - The parent node ID
|
40
|
-
* @param child - The child node ID that the parent depends on
|
41
|
-
* @returns A new graph with the dependency added
|
42
|
-
*/
|
43
|
-
export declare const addDependency: (graph: DependencyGraph, parent: string, child: string) => DependencyGraph;
|
44
|
-
/**
|
45
|
-
* Add a dependency relationship (mutable)
|
46
|
-
* @param graph - The dependency graph to mutate
|
47
|
-
* @param parent - The parent node ID
|
48
|
-
* @param child - The child node ID that the parent depends on
|
49
|
-
*/
|
50
|
-
export declare const addDependencyMutable: (graph: DependencyGraph, parent: string, child: string) => void;
|
51
|
-
/**
|
52
|
-
* Find all nodes that have no dependencies (leaf nodes)
|
53
|
-
*/
|
54
|
-
export declare const findLeafNodes: (graph: DependencyGraph) => Set<string>;
|
55
|
-
/**
|
56
|
-
* Check if all dependencies of a node have been processed
|
57
|
-
*/
|
58
|
-
export declare const areDependenciesReady: (node: string, graph: DependencyGraph, processed: Set<string>) => boolean;
|
59
|
-
/**
|
60
|
-
* Get topological ordering of nodes (children before parents)
|
61
|
-
* This ensures we process dependencies before the nodes that depend on them
|
62
|
-
*
|
63
|
-
* @param graph - The dependency graph
|
64
|
-
* @returns Array of node IDs in topological order
|
65
|
-
*/
|
66
|
-
export declare const topologicalSort: (graph: DependencyGraph) => string[];
|
67
|
-
export declare const decode: (i: {
|
68
|
-
readonly dependencies: {
|
69
|
-
readonly [x: string]: readonly string[];
|
70
|
-
};
|
71
|
-
readonly dependents: {
|
72
|
-
readonly [x: string]: readonly string[];
|
73
|
-
};
|
74
|
-
}, overrideOptions?: import("effect/SchemaAST").ParseOptions) => import("effect/Effect").Effect<{
|
75
|
-
readonly dependencies: {
|
76
|
-
readonly [x: string]: readonly string[];
|
77
|
-
};
|
78
|
-
readonly dependents: {
|
79
|
-
readonly [x: string]: readonly string[];
|
80
|
-
};
|
81
|
-
}, import("effect/ParseResult").ParseError, never>;
|
82
|
-
export declare const decodeSync: (i: {
|
83
|
-
readonly dependencies: {
|
84
|
-
readonly [x: string]: readonly string[];
|
85
|
-
};
|
86
|
-
readonly dependents: {
|
87
|
-
readonly [x: string]: readonly string[];
|
88
|
-
};
|
89
|
-
}, overrideOptions?: import("effect/SchemaAST").ParseOptions) => {
|
90
|
-
readonly dependencies: {
|
91
|
-
readonly [x: string]: readonly string[];
|
92
|
-
};
|
93
|
-
readonly dependents: {
|
94
|
-
readonly [x: string]: readonly string[];
|
95
|
-
};
|
96
|
-
};
|
97
|
-
export declare const encode: (a: {
|
98
|
-
readonly dependencies: {
|
99
|
-
readonly [x: string]: readonly string[];
|
100
|
-
};
|
101
|
-
readonly dependents: {
|
102
|
-
readonly [x: string]: readonly string[];
|
103
|
-
};
|
104
|
-
}, overrideOptions?: import("effect/SchemaAST").ParseOptions) => import("effect/Effect").Effect<{
|
105
|
-
readonly dependencies: {
|
106
|
-
readonly [x: string]: readonly string[];
|
107
|
-
};
|
108
|
-
readonly dependents: {
|
109
|
-
readonly [x: string]: readonly string[];
|
110
|
-
};
|
111
|
-
}, import("effect/ParseResult").ParseError, never>;
|
112
|
-
export declare const encodeSync: (a: {
|
113
|
-
readonly dependencies: {
|
114
|
-
readonly [x: string]: readonly string[];
|
115
|
-
};
|
116
|
-
readonly dependents: {
|
117
|
-
readonly [x: string]: readonly string[];
|
118
|
-
};
|
119
|
-
}, overrideOptions?: import("effect/SchemaAST").ParseOptions) => {
|
120
|
-
readonly dependencies: {
|
121
|
-
readonly [x: string]: readonly string[];
|
122
|
-
};
|
123
|
-
readonly dependents: {
|
124
|
-
readonly [x: string]: readonly string[];
|
125
|
-
};
|
126
|
-
};
|
127
|
-
//# sourceMappingURL=graph.d.ts.map
|
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../../src/lib/graph/graph.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,sBAAsB,CAAA;AAIxC;;;GAGG;AACH,eAAO,MAAM,eAAe;IAC1B;;OAEG;;IAGH;;OAEG;;EAKH,CAAA;AAEF,MAAM,MAAM,eAAe,GAAG,OAAO,eAAe,CAAC,IAAI,CAAA;AAIzD,eAAO,MAAM,IAAI;;;;;;;;;;;;;;CAAuB,CAAA;AAExC;;GAEG;AACH,eAAO,MAAM,MAAM,QAAO,eAItB,CAAA;AAIJ;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,GACxB,OAAO,eAAe,EACtB,QAAQ,MAAM,EACd,OAAO,MAAM,KACZ,eAqBF,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAC/B,OAAO,eAAe,EACtB,QAAQ,MAAM,EACd,OAAO,MAAM,KACZ,IAsBF,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,eAAe,KAAG,GAAG,CAAC,MAAM,CAYhE,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,oBAAoB,GAC/B,MAAM,MAAM,EACZ,OAAO,eAAe,EACtB,WAAW,GAAG,CAAC,MAAM,CAAC,KACrB,OAKF,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GAAI,OAAO,eAAe,KAAG,MAAM,EA2C9D,CAAA;AAID,eAAO,MAAM,MAAM;;;;;;;;;;;;;;kDAA4B,CAAA;AAC/C,eAAO,MAAM,UAAU;;;;;;;;;;;;;;CAAgC,CAAA;AACvD,eAAO,MAAM,MAAM;;;;;;;;;;;;;;kDAA4B,CAAA;AAC/C,eAAO,MAAM,UAAU;;;;;;;;;;;;;;CAAgC,CAAA"}
|