@glyphjs/runtime 0.1.0 → 0.2.0

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/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { GlyphRuntimeConfig, GlyphRuntime, GlyphIR, AnimationConfig, Diagnostic, Block, LayoutHints, ContainerContext, GlyphComponentDefinition, ComponentType, BlockProps, GlyphTheme, Reference, GlyphThemeContext, GlyphComponentProps, InlineNode, ContainerTier } from '@glyphjs/types';
1
+ import { GlyphRuntimeConfig, GlyphRuntime, GlyphIR, AnimationConfig, Diagnostic, Block, LayoutHints, ContainerContext, GlyphComponentDefinition, ComponentType, BlockProps, GlyphTheme, Reference, GlyphThemeContext, InteractionEvent, GlyphComponentProps, InlineNode, ContainerTier } from '@glyphjs/types';
2
2
  export { AnimationConfig } from '@glyphjs/types';
3
3
  import * as react from 'react';
4
4
  import { ReactNode, Component, ErrorInfo, CSSProperties, ComponentType as ComponentType$1, RefObject } from 'react';
@@ -142,13 +142,16 @@ declare class PluginRegistry {
142
142
  interface RuntimeContextValue {
143
143
  registry: PluginRegistry;
144
144
  references: Reference[];
145
+ documentId: string;
145
146
  theme: GlyphThemeContext;
146
147
  onDiagnostic: (diagnostic: Diagnostic) => void;
147
148
  onNavigate: (ref: Reference, targetBlock: Block) => void;
149
+ onInteraction?: (event: InteractionEvent) => void;
148
150
  }
149
151
  interface RuntimeProviderProps {
150
152
  registry: PluginRegistry;
151
153
  references: Reference[];
154
+ documentId: string;
152
155
  theme: 'light' | 'dark' | GlyphTheme | undefined;
153
156
  /** Optional CSS class name applied to the runtime wrapper div. */
154
157
  className?: string;
@@ -156,9 +159,10 @@ interface RuntimeProviderProps {
156
159
  style?: CSSProperties;
157
160
  onDiagnostic?: (diagnostic: Diagnostic) => void;
158
161
  onNavigate?: (ref: Reference, targetBlock: Block) => void;
162
+ onInteraction?: (event: InteractionEvent) => void;
159
163
  children: ReactNode;
160
164
  }
161
- declare function RuntimeProvider({ registry, references, theme, className, style: consumerStyle, onDiagnostic, onNavigate, children, }: RuntimeProviderProps): ReactNode;
165
+ declare function RuntimeProvider({ registry, references, documentId, theme, className, style: consumerStyle, onDiagnostic, onNavigate, onInteraction, children, }: RuntimeProviderProps): ReactNode;
162
166
  /** Access the full runtime context. Throws if used outside RuntimeProvider. */
163
167
  declare function useRuntime(): RuntimeContextValue;
164
168
  /**
@@ -204,9 +208,10 @@ declare function validateComponentDefinition(definition: GlyphComponentDefinitio
204
208
  * @param themeContext - Current theme context passed through to the component.
205
209
  * @param layoutHints - Layout hints (e.g., viewport size, container width) for responsive rendering.
206
210
  * @param containerContext - Container measurement context for container-adaptive layout.
211
+ * @param onInteraction - Optional callback for interactive blocks. Only provided when `block.metadata.interactive` is true.
207
212
  * @returns Fully assembled GlyphComponentProps ready to pass to the component's render function.
208
213
  */
209
- declare function resolveComponentProps<T = unknown>(block: Block, definition: GlyphComponentDefinition<T>, references: Reference[], onNavigate: (ref: Reference) => void, themeContext: GlyphThemeContext, layoutHints: LayoutHints, containerContext: ContainerContext): GlyphComponentProps<T>;
214
+ declare function resolveComponentProps<T = unknown>(block: Block, definition: GlyphComponentDefinition<T>, references: Reference[], onNavigate: (ref: Reference) => void, themeContext: GlyphThemeContext, layoutHints: LayoutHints, containerContext: ContainerContext, onInteraction?: (event: Omit<InteractionEvent, 'documentId'>) => void): GlyphComponentProps<T>;
210
215
 
211
216
  interface LayoutProviderProps {
212
217
  layout: LayoutHints;
@@ -567,4 +572,16 @@ interface SSRPlaceholderProps {
567
572
  */
568
573
  declare function SSRPlaceholder({ width, height, className, children, }: SSRPlaceholderProps): ReactNode;
569
574
 
570
- export { AnimationContext, AnimationProvider, type AnimationState, type BlockAnimationResult, BlockDiagnosticIndicator, BlockRenderer, PluginRegistry as ComponentRegistry, ContainerMeasure, DashboardLayout, DiagnosticsOverlay, DocumentLayout, ErrorBoundary, FallbackRenderer, GlyphBlockquote, GlyphCodeBlock, GlyphDocument, GlyphHeading, GlyphImage, GlyphList, GlyphParagraph, GlyphRawHtml, GlyphThematicBreak, InlineRenderer, LayoutProvider, type NavigationResult, PluginRegistry, PresentationLayout, ReferenceIndicator, type RegistryChangeListener, type RuntimeContextValue, RuntimeProvider, type RuntimeProviderProps, SSRPlaceholder, type SSRPlaceholderProps, ThemeProvider, type ThemeProviderProps, type ValidationResult, builtInRenderers, createGlyphRuntime, createResolveVar, darkTheme, isDarkTheme, lightTheme, mergeThemeDefaults, resolveComponentProps, resolveTheme, resolveTier, useAnimation, useBlockAnimation, useGlyphTheme, useIsClient, useLayout, useNavigation, useReferences, useRuntime, validateComponentDefinition };
575
+ /**
576
+ * Creates a debounced interaction handler that groups events by
577
+ * `blockId + kind`. Each unique stream is debounced independently,
578
+ * so a tab switch fires immediately even while a table filter is
579
+ * being debounced.
580
+ *
581
+ * @param callback - The handler to invoke with the debounced event.
582
+ * @param delay - Debounce window in milliseconds (default: 300).
583
+ * @returns A function with the same signature as `onInteraction`.
584
+ */
585
+ declare function debounceInteractions(callback: (event: InteractionEvent) => void, delay?: number): (event: InteractionEvent) => void;
586
+
587
+ export { AnimationContext, AnimationProvider, type AnimationState, type BlockAnimationResult, BlockDiagnosticIndicator, BlockRenderer, PluginRegistry as ComponentRegistry, ContainerMeasure, DashboardLayout, DiagnosticsOverlay, DocumentLayout, ErrorBoundary, FallbackRenderer, GlyphBlockquote, GlyphCodeBlock, GlyphDocument, GlyphHeading, GlyphImage, GlyphList, GlyphParagraph, GlyphRawHtml, GlyphThematicBreak, InlineRenderer, LayoutProvider, type NavigationResult, PluginRegistry, PresentationLayout, ReferenceIndicator, type RegistryChangeListener, type RuntimeContextValue, RuntimeProvider, type RuntimeProviderProps, SSRPlaceholder, type SSRPlaceholderProps, ThemeProvider, type ThemeProviderProps, type ValidationResult, builtInRenderers, createGlyphRuntime, createResolveVar, darkTheme, debounceInteractions, isDarkTheme, lightTheme, mergeThemeDefaults, resolveComponentProps, resolveTheme, resolveTier, useAnimation, useBlockAnimation, useGlyphTheme, useIsClient, useLayout, useNavigation, useReferences, useRuntime, validateComponentDefinition };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { GlyphRuntimeConfig, GlyphRuntime, GlyphIR, AnimationConfig, Diagnostic, Block, LayoutHints, ContainerContext, GlyphComponentDefinition, ComponentType, BlockProps, GlyphTheme, Reference, GlyphThemeContext, GlyphComponentProps, InlineNode, ContainerTier } from '@glyphjs/types';
1
+ import { GlyphRuntimeConfig, GlyphRuntime, GlyphIR, AnimationConfig, Diagnostic, Block, LayoutHints, ContainerContext, GlyphComponentDefinition, ComponentType, BlockProps, GlyphTheme, Reference, GlyphThemeContext, InteractionEvent, GlyphComponentProps, InlineNode, ContainerTier } from '@glyphjs/types';
2
2
  export { AnimationConfig } from '@glyphjs/types';
3
3
  import * as react from 'react';
4
4
  import { ReactNode, Component, ErrorInfo, CSSProperties, ComponentType as ComponentType$1, RefObject } from 'react';
@@ -142,13 +142,16 @@ declare class PluginRegistry {
142
142
  interface RuntimeContextValue {
143
143
  registry: PluginRegistry;
144
144
  references: Reference[];
145
+ documentId: string;
145
146
  theme: GlyphThemeContext;
146
147
  onDiagnostic: (diagnostic: Diagnostic) => void;
147
148
  onNavigate: (ref: Reference, targetBlock: Block) => void;
149
+ onInteraction?: (event: InteractionEvent) => void;
148
150
  }
149
151
  interface RuntimeProviderProps {
150
152
  registry: PluginRegistry;
151
153
  references: Reference[];
154
+ documentId: string;
152
155
  theme: 'light' | 'dark' | GlyphTheme | undefined;
153
156
  /** Optional CSS class name applied to the runtime wrapper div. */
154
157
  className?: string;
@@ -156,9 +159,10 @@ interface RuntimeProviderProps {
156
159
  style?: CSSProperties;
157
160
  onDiagnostic?: (diagnostic: Diagnostic) => void;
158
161
  onNavigate?: (ref: Reference, targetBlock: Block) => void;
162
+ onInteraction?: (event: InteractionEvent) => void;
159
163
  children: ReactNode;
160
164
  }
161
- declare function RuntimeProvider({ registry, references, theme, className, style: consumerStyle, onDiagnostic, onNavigate, children, }: RuntimeProviderProps): ReactNode;
165
+ declare function RuntimeProvider({ registry, references, documentId, theme, className, style: consumerStyle, onDiagnostic, onNavigate, onInteraction, children, }: RuntimeProviderProps): ReactNode;
162
166
  /** Access the full runtime context. Throws if used outside RuntimeProvider. */
163
167
  declare function useRuntime(): RuntimeContextValue;
164
168
  /**
@@ -204,9 +208,10 @@ declare function validateComponentDefinition(definition: GlyphComponentDefinitio
204
208
  * @param themeContext - Current theme context passed through to the component.
205
209
  * @param layoutHints - Layout hints (e.g., viewport size, container width) for responsive rendering.
206
210
  * @param containerContext - Container measurement context for container-adaptive layout.
211
+ * @param onInteraction - Optional callback for interactive blocks. Only provided when `block.metadata.interactive` is true.
207
212
  * @returns Fully assembled GlyphComponentProps ready to pass to the component's render function.
208
213
  */
209
- declare function resolveComponentProps<T = unknown>(block: Block, definition: GlyphComponentDefinition<T>, references: Reference[], onNavigate: (ref: Reference) => void, themeContext: GlyphThemeContext, layoutHints: LayoutHints, containerContext: ContainerContext): GlyphComponentProps<T>;
214
+ declare function resolveComponentProps<T = unknown>(block: Block, definition: GlyphComponentDefinition<T>, references: Reference[], onNavigate: (ref: Reference) => void, themeContext: GlyphThemeContext, layoutHints: LayoutHints, containerContext: ContainerContext, onInteraction?: (event: Omit<InteractionEvent, 'documentId'>) => void): GlyphComponentProps<T>;
210
215
 
211
216
  interface LayoutProviderProps {
212
217
  layout: LayoutHints;
@@ -567,4 +572,16 @@ interface SSRPlaceholderProps {
567
572
  */
568
573
  declare function SSRPlaceholder({ width, height, className, children, }: SSRPlaceholderProps): ReactNode;
569
574
 
570
- export { AnimationContext, AnimationProvider, type AnimationState, type BlockAnimationResult, BlockDiagnosticIndicator, BlockRenderer, PluginRegistry as ComponentRegistry, ContainerMeasure, DashboardLayout, DiagnosticsOverlay, DocumentLayout, ErrorBoundary, FallbackRenderer, GlyphBlockquote, GlyphCodeBlock, GlyphDocument, GlyphHeading, GlyphImage, GlyphList, GlyphParagraph, GlyphRawHtml, GlyphThematicBreak, InlineRenderer, LayoutProvider, type NavigationResult, PluginRegistry, PresentationLayout, ReferenceIndicator, type RegistryChangeListener, type RuntimeContextValue, RuntimeProvider, type RuntimeProviderProps, SSRPlaceholder, type SSRPlaceholderProps, ThemeProvider, type ThemeProviderProps, type ValidationResult, builtInRenderers, createGlyphRuntime, createResolveVar, darkTheme, isDarkTheme, lightTheme, mergeThemeDefaults, resolveComponentProps, resolveTheme, resolveTier, useAnimation, useBlockAnimation, useGlyphTheme, useIsClient, useLayout, useNavigation, useReferences, useRuntime, validateComponentDefinition };
575
+ /**
576
+ * Creates a debounced interaction handler that groups events by
577
+ * `blockId + kind`. Each unique stream is debounced independently,
578
+ * so a tab switch fires immediately even while a table filter is
579
+ * being debounced.
580
+ *
581
+ * @param callback - The handler to invoke with the debounced event.
582
+ * @param delay - Debounce window in milliseconds (default: 300).
583
+ * @returns A function with the same signature as `onInteraction`.
584
+ */
585
+ declare function debounceInteractions(callback: (event: InteractionEvent) => void, delay?: number): (event: InteractionEvent) => void;
586
+
587
+ export { AnimationContext, AnimationProvider, type AnimationState, type BlockAnimationResult, BlockDiagnosticIndicator, BlockRenderer, PluginRegistry as ComponentRegistry, ContainerMeasure, DashboardLayout, DiagnosticsOverlay, DocumentLayout, ErrorBoundary, FallbackRenderer, GlyphBlockquote, GlyphCodeBlock, GlyphDocument, GlyphHeading, GlyphImage, GlyphList, GlyphParagraph, GlyphRawHtml, GlyphThematicBreak, InlineRenderer, LayoutProvider, type NavigationResult, PluginRegistry, PresentationLayout, ReferenceIndicator, type RegistryChangeListener, type RuntimeContextValue, RuntimeProvider, type RuntimeProviderProps, SSRPlaceholder, type SSRPlaceholderProps, ThemeProvider, type ThemeProviderProps, type ValidationResult, builtInRenderers, createGlyphRuntime, createResolveVar, darkTheme, debounceInteractions, isDarkTheme, lightTheme, mergeThemeDefaults, resolveComponentProps, resolveTheme, resolveTier, useAnimation, useBlockAnimation, useGlyphTheme, useIsClient, useLayout, useNavigation, useReferences, useRuntime, validateComponentDefinition };
package/dist/index.js CHANGED
@@ -394,11 +394,13 @@ var RuntimeContext = createContext(null);
394
394
  function RuntimeProvider({
395
395
  registry,
396
396
  references,
397
+ documentId,
397
398
  theme,
398
399
  className,
399
400
  style: consumerStyle,
400
401
  onDiagnostic,
401
402
  onNavigate,
403
+ onInteraction,
402
404
  children
403
405
  }) {
404
406
  const resolvedThemeObject = useMemo(() => resolveTheme(theme), [theme]);
@@ -414,11 +416,13 @@ function RuntimeProvider({
414
416
  () => ({
415
417
  registry,
416
418
  references,
419
+ documentId,
417
420
  theme: resolvedTheme,
418
421
  onDiagnostic: onDiagnostic ?? noop,
419
- onNavigate: onNavigate ?? noop
422
+ onNavigate: onNavigate ?? noop,
423
+ onInteraction
420
424
  }),
421
- [registry, references, resolvedTheme, onDiagnostic, onNavigate]
425
+ [registry, references, documentId, resolvedTheme, onDiagnostic, onNavigate, onInteraction]
422
426
  );
423
427
  const style = useMemo(
424
428
  () => ({ ...resolvedThemeObject.variables, ...consumerStyle }),
@@ -789,7 +793,7 @@ var builtInRenderers = {
789
793
  };
790
794
 
791
795
  // src/plugins/resolve-props.ts
792
- function resolveComponentProps(block, definition, references, onNavigate, themeContext, layoutHints, containerContext) {
796
+ function resolveComponentProps(block, definition, references, onNavigate, themeContext, layoutHints, containerContext, onInteraction) {
793
797
  const parseResult = definition.schema.safeParse(block.data);
794
798
  const data = parseResult.success ? parseResult.data : (() => {
795
799
  const err = parseResult.error;
@@ -819,7 +823,7 @@ function resolveComponentProps(block, definition, references, onNavigate, themeC
819
823
  }
820
824
  }
821
825
  }
822
- return {
826
+ const props = {
823
827
  data,
824
828
  block,
825
829
  outgoingRefs,
@@ -829,6 +833,10 @@ function resolveComponentProps(block, definition, references, onNavigate, themeC
829
833
  layout: layoutHints,
830
834
  container: containerContext
831
835
  };
836
+ if (onInteraction) {
837
+ props.onInteraction = onInteraction;
838
+ }
839
+ return props;
832
840
  }
833
841
  var defaultConfig = {
834
842
  enabled: true,
@@ -1018,7 +1026,7 @@ function ReferenceIndicator({
1018
1026
  );
1019
1027
  }
1020
1028
  function BlockDispatch({ block, layout, container }) {
1021
- const { registry, references, theme, onNavigate } = useRuntime();
1029
+ const { registry, references, theme, documentId, onNavigate, onInteraction } = useRuntime();
1022
1030
  const { incomingRefs, outgoingRefs } = useReferences(block.id);
1023
1031
  const hasRefs = incomingRefs.length > 0 || outgoingRefs.length > 0;
1024
1032
  if (block.type.startsWith("ui:")) {
@@ -1034,6 +1042,9 @@ function BlockDispatch({ block, layout, container }) {
1034
1042
  }
1035
1043
  }
1036
1044
  }
1045
+ const handleInteraction = onInteraction && block.metadata?.interactive === true ? (event) => {
1046
+ onInteraction({ ...event, documentId });
1047
+ } : void 0;
1037
1048
  let content;
1038
1049
  const overrideDef = registry.getOverride(block.type);
1039
1050
  if (overrideDef) {
@@ -1052,7 +1063,8 @@ function BlockDispatch({ block, layout, container }) {
1052
1063
  handleNavigate,
1053
1064
  theme,
1054
1065
  layout,
1055
- container
1066
+ container,
1067
+ handleInteraction
1056
1068
  );
1057
1069
  const Renderer = definition.render;
1058
1070
  content = /* @__PURE__ */ jsx(Renderer, { ...props });
@@ -1644,7 +1656,7 @@ function createGlyphRuntime(config) {
1644
1656
  setThemeState(currentTheme);
1645
1657
  setVersion(registryVersion);
1646
1658
  }, []);
1647
- useMemo(() => {
1659
+ useEffect(() => {
1648
1660
  listeners.add(forceUpdate);
1649
1661
  return () => {
1650
1662
  listeners.delete(forceUpdate);
@@ -1655,9 +1667,11 @@ function createGlyphRuntime(config) {
1655
1667
  {
1656
1668
  registry,
1657
1669
  references: ir.references,
1670
+ documentId: ir.id,
1658
1671
  theme,
1659
1672
  onDiagnostic: config.onDiagnostic,
1660
1673
  onNavigate: config.onNavigate,
1674
+ onInteraction: config.onInteraction,
1661
1675
  children: /* @__PURE__ */ jsx(GlyphDocument, { ir, className, animation: config.animation })
1662
1676
  }
1663
1677
  );
@@ -1709,6 +1723,25 @@ function SSRPlaceholder({
1709
1723
  return /* @__PURE__ */ jsx(Fragment, { children });
1710
1724
  }
1711
1725
 
1712
- export { AnimationContext, AnimationProvider, BlockDiagnosticIndicator, BlockRenderer, PluginRegistry as ComponentRegistry, ContainerMeasure, DashboardLayout, DiagnosticsOverlay, DocumentLayout, ErrorBoundary, FallbackRenderer, GlyphBlockquote, GlyphCodeBlock, GlyphDocument, GlyphHeading, GlyphImage, GlyphList, GlyphParagraph, GlyphRawHtml, GlyphThematicBreak, InlineRenderer, LayoutProvider, PluginRegistry, PresentationLayout, ReferenceIndicator, RuntimeProvider, SSRPlaceholder, ThemeProvider, builtInRenderers, createGlyphRuntime, createResolveVar, darkTheme, isDarkTheme, lightTheme, mergeThemeDefaults, resolveComponentProps, resolveTheme, resolveTier, useAnimation, useBlockAnimation, useGlyphTheme, useIsClient, useLayout, useNavigation, useReferences, useRuntime, validateComponentDefinition };
1726
+ // src/debounce.ts
1727
+ function debounceInteractions(callback, delay = 300) {
1728
+ const timers = /* @__PURE__ */ new Map();
1729
+ return (event) => {
1730
+ const key = `${event.blockId}:${event.kind}`;
1731
+ const existing = timers.get(key);
1732
+ if (existing !== void 0) {
1733
+ clearTimeout(existing);
1734
+ }
1735
+ timers.set(
1736
+ key,
1737
+ setTimeout(() => {
1738
+ timers.delete(key);
1739
+ callback(event);
1740
+ }, delay)
1741
+ );
1742
+ };
1743
+ }
1744
+
1745
+ export { AnimationContext, AnimationProvider, BlockDiagnosticIndicator, BlockRenderer, PluginRegistry as ComponentRegistry, ContainerMeasure, DashboardLayout, DiagnosticsOverlay, DocumentLayout, ErrorBoundary, FallbackRenderer, GlyphBlockquote, GlyphCodeBlock, GlyphDocument, GlyphHeading, GlyphImage, GlyphList, GlyphParagraph, GlyphRawHtml, GlyphThematicBreak, InlineRenderer, LayoutProvider, PluginRegistry, PresentationLayout, ReferenceIndicator, RuntimeProvider, SSRPlaceholder, ThemeProvider, builtInRenderers, createGlyphRuntime, createResolveVar, darkTheme, debounceInteractions, isDarkTheme, lightTheme, mergeThemeDefaults, resolveComponentProps, resolveTheme, resolveTier, useAnimation, useBlockAnimation, useGlyphTheme, useIsClient, useLayout, useNavigation, useReferences, useRuntime, validateComponentDefinition };
1713
1746
  //# sourceMappingURL=index.js.map
1714
1747
  //# sourceMappingURL=index.js.map