Skip to content

URI System

The URI (Uniform Resource Identifier) system in the content model provides a consistent addressing scheme for content across different storage adapters. It serves as the foundation for content identification, retrieval, and referencing.

Core Concepts

URI Structure

Content URIs follow a consistent structure:

[scheme:][//authority/]path[?query][#fragment]
  • Scheme: Optional protocol identifier (e.g., file:, http:, memory:)
  • Authority: Optional host/authority component
  • Path: Required path component that identifies the content location
  • Query: Optional query parameters
  • Fragment: Optional fragment identifier for addressing parts of content

Relative vs. Absolute URIs

The content system supports both relative and absolute URIs:

  • Absolute URIs: Include scheme and complete addressing information
    • Examples: file:///content/articles/intro.md, http://api.example.com/content/data.json
  • Relative URIs: Resolved against a base URI
    • Examples: articles/intro.md, ../shared/header.md

URI Resolution

Relative URIs are resolved against a base URI using standard URI resolution algorithms:

  1. If the URI is absolute, use it as-is
  2. If the URI is relative, combine it with the base URI according to RFC 3986 rules
  3. Normalize the resulting path (resolve . and .. segments)

URI Components

Path Component

The path component is the most fundamental part of a content URI:

  • Follows a hierarchical structure (directories/subdirectories)
  • Uses forward slashes (/) as separators
  • May include file extensions to indicate content type
  • Special paths:
    • Root path (/)
    • Current path (.)
    • Parent path (..)

Scheme Component

The scheme identifies the adapter type and protocol:

  • file: - Filesystem adapter
  • memory: - Memory adapter
  • http: or https: - HTTP adapter
  • indexeddb: - IndexedDB adapter
  • localStorage: - LocalStorage adapter

When no scheme is specified, the default adapter is used.

Query Component

The query component provides additional parameters for content operations:

  • Format specification: ?format=json
  • Version selection: ?version=2.1
  • Filtering: ?tags=important&status=published
  • Projection: ?fields=title,summary,publishedDate

Fragment Component

The fragment component addresses specific parts within content:

  • Section references: #introduction
  • Line numbers: #L42-L50
  • Time positions (for media): #t=10,20
  • Selection ranges: #char=0,100

URI Patterns

URI patterns allow matching multiple content items using glob-like syntax:

  • **/*.md - All Markdown files in any directory
  • articles/*.json - All JSON files in the articles directory
  • data/{users,products}/*.json - All JSON files in users or products directories
  • *.{md,mdx} - All Markdown and MDX files in the current directory

Patterns are used for:

  • Listing content with store.list(pattern)
  • Content watching with store.watch(pattern, callback)
  • Batch operations

URI Mapping

URIs can be mapped between different representations:

Physical to Logical Mapping

Content adapters map physical storage locations to logical URIs:

  • Filesystem paths: /var/content/articles/intro.mdarticles/intro.md
  • Database records: db:collection:12345articles/intro.md
  • Remote resources: https://api.example.com/v1/content/12345articles/intro.md

URI Normalization

URIs are normalized to ensure consistent addressing:

  • Path normalization: Resolve . and .. segments
  • Case normalization: Convert to lowercase if case-insensitive
  • Trailing slash handling: Remove or add consistently
  • Extension normalization: Add default extensions when missing

Working with URIs

URI Parsing

The content system provides utilities for URI parsing:

typescript
import { parseUri } from '@lib/content/uri'

const uri = 'file:///content/articles/intro.md?version=latest#summary'
const parsed = parseUri(uri)

// Result:
// {
//   scheme: 'file',
//   authority: '',
//   path: '/content/articles/intro.md',
//   query: 'version=latest',
//   fragment: 'summary',
//   params: { version: 'latest' }
// }

URI Building

Creating URIs programmatically:

typescript
import { buildUri } from '@lib/content/uri'

const uri = buildUri({
  scheme: 'memory',
  path: 'articles/intro.md',
  query: { version: 'latest' },
  fragment: 'summary',
})

// Result: memory:articles/intro.md?version=latest#summary

URI Resolution

Resolving relative URIs against a base URI:

typescript
import { resolveUri } from '@lib/content/uri'

const baseUri = 'articles/guides/'
const relativeUri = '../tutorials/getting-started.md'
const resolved = resolveUri(baseUri, relativeUri)

// Result: articles/tutorials/getting-started.md

Pattern Matching

Testing if a URI matches a pattern:

typescript
import { matchesPattern } from '@lib/content/uri'

const pattern = 'articles/**/*.md'
const uri = 'articles/guides/intro.md'
const matches = matchesPattern(uri, pattern)

// Result: true

URI Handling in Adapters

Each adapter implements URI handling specific to its storage mechanism:

  • FileSystemAdapter: Maps between filesystem paths and logical URIs
  • MemoryAdapter: Uses URIs as keys in an in-memory map
  • HttpAdapter: Maps between HTTP URLs and logical URIs
  • IndexedDBAdapter: Uses URIs as keys in object stores

Best Practices

URI Design

  • Use descriptive, hierarchical paths that reflect content organization
  • Prefer lowercase URIs for consistency
  • Use file extensions to indicate content type
  • Keep URIs reasonably short and human-readable
  • Avoid special characters that might require encoding

URI Management

  • Store canonical URIs with content references
  • Use relative URIs for content references when possible
  • Prefer patterns over enumeration for batch operations
  • Cache URI resolution results when processing multiple references

URI Stability

  • Maintain stable URIs for important content
  • Implement redirects when URIs must change
  • Use content identifiers separate from URIs for permanent references
  • Consider versioning in the URI scheme for immutable content

Integration with Web Standards

The content URI system aligns with web standards:

  • Compatible with RFC 3986 URI syntax
  • Supports glob patterns for content matching
  • Works with standard URL objects in browser environments
  • Integrates with Web API URL for parsing

Released under the MIT License.