markstream-angular 2.0.21 → 2.0.24

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.css CHANGED
@@ -143,19 +143,8 @@ markstream-angular {
143
143
  width: 100%;
144
144
  }
145
145
 
146
- .markstream-angular .markstream-angular-text__stream-delta {
147
- animation-duration: var(--stream-update-fade-duration, var(--fade-duration, var(--typewriter-fade-duration, 280ms)));
148
- animation-timing-function: var(--stream-update-fade-ease, var(--fade-ease, var(--typewriter-fade-ease, cubic-bezier(0.33, 0, 0.67, 1))));
149
- animation-fill-mode: both;
150
- }
151
146
 
152
- .markstream-angular .markstream-angular-text__stream-delta--a {
153
- animation-name: markstream-angular-text-stream-update-fade-a;
154
- }
155
147
 
156
- .markstream-angular .markstream-angular-text__stream-delta--b {
157
- animation-name: markstream-angular-text-stream-update-fade-b;
158
- }
159
148
 
160
149
  .markstream-angular h1,
161
150
  .markstream-angular h2,
@@ -259,15 +248,7 @@ markstream-angular {
259
248
  50% { opacity: var(--underline-opacity, 0.35); }
260
249
  }
261
250
 
262
- @keyframes markstream-angular-text-stream-update-fade-a {
263
- from { opacity: 0; }
264
- to { opacity: 1; }
265
- }
266
251
 
267
- @keyframes markstream-angular-text-stream-update-fade-b {
268
- from { opacity: 0; }
269
- to { opacity: 1; }
270
- }
271
252
 
272
253
  @media (prefers-reduced-motion: reduce) {
273
254
  .markstream-angular .node-placeholder::before {
@@ -279,9 +260,6 @@ markstream-angular {
279
260
  opacity: var(--underline-rest-opacity, 0.18);
280
261
  }
281
262
 
282
- .markstream-angular .markstream-angular-text__stream-delta {
283
- animation: none !important;
284
- }
285
263
 
286
264
  .markstream-angular .fade-node,
287
265
  .markstream-angular .typewriter-node,
@@ -1575,3 +1553,27 @@ body > div[id^="dmermaid-"] {
1575
1553
  overflow: auto;
1576
1554
  margin: 0;
1577
1555
  }
1556
+
1557
+ /* Streaming words share timing and identity across framework adapters. */
1558
+ :where(.markstream-angular) .text-node-stream-delta {
1559
+ animation: markstream-angular-word-fade var(--stream-update-fade-duration, var(--fade-duration, 700ms)) var(--stream-update-fade-ease, var(--fade-ease, cubic-bezier(0.37, 0.55, 0.86, 0.88))) both;
1560
+ }
1561
+ :where(.markstream-angular) .text-node-stream-final {
1562
+ animation: none !important;
1563
+ opacity: 1;
1564
+ }
1565
+ @keyframes markstream-angular-word-fade {
1566
+ from { opacity: 0; }
1567
+ to { opacity: 1; }
1568
+ }
1569
+ @media (prefers-reduced-motion: reduce) {
1570
+ :where(.markstream-angular) .text-node-stream-delta { animation-duration: 0s !important; }
1571
+ }
1572
+
1573
+ :where(.markstream-angular)[data-stream-final] .fade-node,
1574
+ :where(.markstream-angular)[data-stream-final] .fade-enter-active,
1575
+ :where(.markstream-angular)[data-stream-final] .typewriter-enter-active {
1576
+ animation: none !important;
1577
+ transition: none !important;
1578
+ opacity: 1;
1579
+ }
package/dist/index.d.ts CHANGED
@@ -1,8 +1,9 @@
1
- import { SmoothMarkdownStreamOptions } from 'markstream-core';
1
+ import * as markstream_core from 'markstream-core';
2
+ import { SmoothMarkdownStreamOptions, StreamingTextScope, SmoothMarkdownStreamSnapshot } from 'markstream-core';
2
3
  export { SmoothMarkdownStreamOptions } from 'markstream-core';
3
4
  import { ParsedNode, BaseNode, HtmlPolicy, ParseOptions, MarkdownIt } from 'stream-markdown-parser';
4
5
  import * as i0 from '@angular/core';
5
- import { Type, AfterViewInit, OnChanges, OnDestroy, OnInit, EventEmitter, SimpleChanges, InjectionToken, ElementRef } from '@angular/core';
6
+ import { Type, AfterViewInit, OnChanges, OnDestroy, InjectionToken, ElementRef, OnInit, EventEmitter, SimpleChanges } from '@angular/core';
6
7
  import * as markstream_angular from 'markstream-angular';
7
8
 
8
9
  type CustomComponentMap = Record<string, Type<unknown>>;
@@ -706,30 +707,30 @@ declare class InfographicBlockNodeComponent implements AfterViewInit, OnChanges,
706
707
  static ɵcmp: i0.ɵɵComponentDeclaration<InfographicBlockNodeComponent, "markstream-angular-infographic-block-node", never, { "node": { "alias": "node"; "required": true; }; "context": { "alias": "context"; "required": false; }; "props": { "alias": "props"; "required": false; }; }, {}, never, never, true, never>;
707
708
  }
708
709
 
709
- interface StreamSegment$1 {
710
- id: number;
711
- content: string;
712
- fading: boolean;
710
+ interface SmoothStreamingScope {
711
+ textScope?: StreamingTextScope;
712
+ isSmoothStreamingEnabled: () => boolean;
713
713
  }
714
- declare class InlineCodeNodeComponent implements OnChanges {
714
+ declare const MARKSTREAM_SMOOTH_STREAMING_SCOPE: InjectionToken<SmoothStreamingScope>;
715
+
716
+ declare class InlineCodeNodeComponent implements OnChanges, AfterViewInit, OnDestroy {
717
+ private readonly scope?;
715
718
  node: AngularRenderableNode;
716
719
  context?: AngularRenderContext;
717
720
  indexKey?: string;
718
721
  typewriter?: boolean;
719
722
  fade?: boolean;
720
- segments: StreamSegment$1[];
721
- private renderedCode;
722
- private nextSegmentId;
723
+ host?: ElementRef<HTMLElement>;
724
+ initial: string;
725
+ private initialized;
726
+ private binding?;
727
+ private readonly localScope;
728
+ constructor(scope?: SmoothStreamingScope);
723
729
  ngOnChanges(): void;
724
- get settledCode(): string;
725
- get streamedDelta(): string;
726
- streamedDeltaClass(segment: StreamSegment$1): "markstream-angular-text__stream-delta--a" | "markstream-angular-text__stream-delta--b";
727
- get fadeEnabled(): boolean;
728
- get typewriterEnabled(): boolean;
729
- trackSegment(_index: number, segment: StreamSegment$1): number;
730
- settleSegment(segmentId: number): void;
731
- private setFullCode;
732
- static ɵfac: i0.ɵɵFactoryDeclaration<InlineCodeNodeComponent, never>;
730
+ ngAfterViewInit(): void;
731
+ ngOnDestroy(): void;
732
+ private update;
733
+ static ɵfac: i0.ɵɵFactoryDeclaration<InlineCodeNodeComponent, [{ optional: true; }]>;
733
734
  static ɵcmp: i0.ɵɵComponentDeclaration<InlineCodeNodeComponent, "markstream-angular-inline-code-node", never, { "node": { "alias": "node"; "required": true; }; "context": { "alias": "context"; "required": false; }; "indexKey": { "alias": "indexKey"; "required": false; }; "typewriter": { "alias": "typewriter"; "required": false; }; "fade": { "alias": "fade"; "required": false; }; }, {}, never, never, true, never>;
734
735
  }
735
736
 
@@ -992,7 +993,11 @@ declare class NodeRendererComponent implements NodeRendererProps, OnChanges, OnI
992
993
  private readonly cdr;
993
994
  private readonly hostRef;
994
995
  private readonly smoothStream;
996
+ private finalReady;
997
+ private streamBridge?;
995
998
  private readonly parentSmoothStreamingScope;
999
+ private readonly ownTextScope;
1000
+ get textScope(): markstream_core.StreamingTextScope;
996
1001
  private rootRef?;
997
1002
  private typewriterCursorRef?;
998
1003
  content: string;
@@ -1211,11 +1216,6 @@ declare class SafeAttrsDirective implements OnChanges {
1211
1216
  static ɵdir: i0.ɵɵDirectiveDeclaration<SafeAttrsDirective, "[markstreamSafeAttrs]", never, { "markstreamSafeAttrs": { "alias": "markstreamSafeAttrs"; "required": false; }; }, {}, never, never, true, never>;
1212
1217
  }
1213
1218
 
1214
- interface SmoothStreamingScope {
1215
- isSmoothStreamingEnabled: () => boolean;
1216
- }
1217
- declare const MARKSTREAM_SMOOTH_STREAMING_SCOPE: InjectionToken<SmoothStreamingScope>;
1218
-
1219
1219
  declare class StrikethroughNodeComponent {
1220
1220
  node: AngularRenderableNode;
1221
1221
  context?: AngularRenderContext;
@@ -1286,33 +1286,24 @@ declare class TableNodeComponent implements OnDestroy {
1286
1286
  static ɵcmp: i0.ɵɵComponentDeclaration<TableNodeComponent, "markstream-angular-table-node", never, { "node": { "alias": "node"; "required": true; }; "context": { "alias": "context"; "required": false; }; "indexKey": { "alias": "indexKey"; "required": false; }; }, {}, never, never, true, never>;
1287
1287
  }
1288
1288
 
1289
- interface StreamSegment {
1290
- id: number;
1291
- content: string;
1292
- fading: boolean;
1293
- }
1294
- declare class TextNodeComponent implements OnChanges {
1289
+ declare class TextNodeComponent implements OnChanges, AfterViewInit, OnDestroy {
1290
+ private readonly scope?;
1295
1291
  node: AngularRenderableNode;
1296
1292
  context?: AngularRenderContext;
1297
1293
  indexKey?: string;
1298
1294
  typewriter?: boolean;
1299
1295
  fade?: boolean;
1300
- segments: StreamSegment[];
1301
- private renderedText;
1302
- private nextSegmentId;
1303
- private lastStreamRenderVersion?;
1296
+ host?: ElementRef<HTMLElement>;
1297
+ initial: string;
1298
+ private initialized;
1299
+ private binding?;
1300
+ private readonly localScope;
1301
+ constructor(scope?: SmoothStreamingScope);
1304
1302
  ngOnChanges(): void;
1305
- get centered(): boolean;
1306
- get settledText(): string;
1307
- get streamedDelta(): string;
1308
- streamedDeltaClass(segment: StreamSegment): "markstream-angular-text__stream-delta--a" | "markstream-angular-text__stream-delta--b";
1309
- get fadeEnabled(): boolean;
1310
- get typewriterEnabled(): boolean;
1311
- trackSegment(_index: number, segment: StreamSegment): number;
1312
- settleSegment(segmentId: number): void;
1313
- private setFullText;
1314
- private settleFadingSegments;
1315
- static ɵfac: i0.ɵɵFactoryDeclaration<TextNodeComponent, never>;
1303
+ ngAfterViewInit(): void;
1304
+ ngOnDestroy(): void;
1305
+ private update;
1306
+ static ɵfac: i0.ɵɵFactoryDeclaration<TextNodeComponent, [{ optional: true; }]>;
1316
1307
  static ɵcmp: i0.ɵɵComponentDeclaration<TextNodeComponent, "markstream-angular-text-node", never, { "node": { "alias": "node"; "required": true; }; "context": { "alias": "context"; "required": false; }; "indexKey": { "alias": "indexKey"; "required": false; }; "typewriter": { "alias": "typewriter"; "required": false; }; "fade": { "alias": "fade"; "required": false; }; }, {}, never, never, true, never>;
1317
1308
  }
1318
1309
 
@@ -1466,6 +1457,7 @@ declare class SmoothMarkdownStreamService implements OnDestroy {
1466
1457
  * rebuild / markForCheck.
1467
1458
  */
1468
1459
  subscribe(listener: () => void): () => void;
1460
+ getSnapshot: () => SmoothMarkdownStreamSnapshot;
1469
1461
  get source(): string;
1470
1462
  get visible(): string;
1471
1463
  get done(): boolean;
@@ -1476,8 +1468,12 @@ declare class SmoothMarkdownStreamService implements OnDestroy {
1476
1468
  finish(options?: {
1477
1469
  flush?: boolean;
1478
1470
  }): void;
1479
- flush(): void;
1480
- reset(initialMarkdown?: string): void;
1471
+ flush(options?: {
1472
+ maxChars?: number;
1473
+ }): void;
1474
+ reset(initialMarkdown?: string, options?: {
1475
+ prefixKnown?: boolean;
1476
+ }): void;
1481
1477
  pause(): void;
1482
1478
  resume(): void;
1483
1479
  private syncSnapshot;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "markstream-angular",
3
3
  "type": "module",
4
- "version": "2.0.21",
4
+ "version": "2.0.24",
5
5
  "description": "Angular 20+ standalone streaming Markdown renderer for AI chat, LLM token streams, SSE/WebSocket output, incomplete Markdown, Mermaid, KaTeX, stream-diffs powered code blocks, and safe Angular component rendering.",
6
6
  "author": "Simon He",
7
7
  "license": "MIT",
@@ -94,8 +94,8 @@
94
94
  },
95
95
  "dependencies": {
96
96
  "@floating-ui/dom": "^1.8.0",
97
- "markstream-core": "2.0.21",
98
- "stream-markdown-parser": "1.2.22"
97
+ "stream-markdown-parser": "1.2.25",
98
+ "markstream-core": "2.0.24"
99
99
  },
100
100
  "devDependencies": {
101
101
  "@angular/common": "^20.3.26",