@embedpdf/models 2.0.0-next.1 → 2.0.0-next.3

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.ts CHANGED
@@ -15,6 +15,7 @@ export * from './color';
15
15
  export * from './date';
16
16
  export * from './helpers';
17
17
  export * from './uuid';
18
+ export * from './compound-task';
18
19
  /**
19
20
  * ignore will do nothing when called.
20
21
  *
package/dist/index.js CHANGED
@@ -367,6 +367,7 @@ class PerfLogger {
367
367
  * create new PerfLogger
368
368
  */
369
369
  constructor() {
370
+ this.marks = /* @__PURE__ */ new Map();
370
371
  }
371
372
  /** {@inheritDoc Logger.isEnabled} */
372
373
  isEnabled() {
@@ -386,21 +387,23 @@ class PerfLogger {
386
387
  }
387
388
  /** {@inheritDoc Logger.perf} */
388
389
  perf(source, category, event, phase, identifier, ...args) {
390
+ const markName = `${source}.${category}.${event}.${phase}.${identifier}`;
389
391
  switch (phase) {
390
392
  case "Begin":
391
- globalThis.performance.mark(`${source}.${category}.${event}.${phase}.${identifier}`, {
392
- detail: args
393
- });
393
+ globalThis.performance.mark(markName, { detail: args });
394
+ this.marks.set(`${source}.${category}.${event}.${identifier}`, Date.now());
394
395
  break;
395
396
  case "End":
396
- globalThis.performance.mark(`${source}.${category}.${event}.${phase}.${identifier}`, {
397
- detail: args
398
- });
399
- globalThis.performance.measure(
400
- `${source}.${category}.${event}.Measure.${identifier}`,
401
- `${source}.${category}.${event}.Begin.${identifier}`,
402
- `${source}.${category}.${event}.End.${identifier}`
403
- );
397
+ globalThis.performance.mark(markName, { detail: args });
398
+ const measureName = `${source}.${category}.${event}.Measure.${identifier}`;
399
+ const beginMark = `${source}.${category}.${event}.Begin.${identifier}`;
400
+ globalThis.performance.measure(measureName, beginMark, markName);
401
+ const startTime = this.marks.get(`${source}.${category}.${event}.${identifier}`);
402
+ if (startTime) {
403
+ const duration = Date.now() - startTime;
404
+ console.info(`⏱️ ${source}.${category}.${event}.${identifier}: ${duration}ms`);
405
+ this.marks.delete(`${source}.${category}.${event}.${identifier}`);
406
+ }
404
407
  break;
405
408
  }
406
409
  }
@@ -1694,6 +1697,7 @@ const blendModeSelectOptions = BLEND_MODE_INFOS.map((info) => ({
1694
1697
  value: info.id,
1695
1698
  label: info.label
1696
1699
  }));
1700
+ const blendModeValues = BLEND_MODE_INFOS.map((info) => info.id);
1697
1701
  function uiBlendModeDisplay(value) {
1698
1702
  return value === MixedBlendMode ? "(mixed)" : blendModeLabel(value);
1699
1703
  }
@@ -1782,11 +1786,196 @@ function uuidV4() {
1782
1786
  const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
1783
1787
  return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
1784
1788
  }
1789
+ class CompoundTask extends Task {
1790
+ constructor(config = {}) {
1791
+ super();
1792
+ this.children = /* @__PURE__ */ new Map();
1793
+ this.childResults = [];
1794
+ this.completedCount = 0;
1795
+ this.expectedCount = 0;
1796
+ this.isFinalized = false;
1797
+ this.config = {
1798
+ aggregate: config.aggregate ?? ((results) => results),
1799
+ onChildComplete: config.onChildComplete ?? (() => {
1800
+ }),
1801
+ failFast: config.failFast ?? true
1802
+ };
1803
+ }
1804
+ /**
1805
+ * Add a child task - automatically wires up completion handling
1806
+ */
1807
+ addChild(child, index) {
1808
+ if (this.state.stage !== TaskStage.Pending) {
1809
+ if (this.state.stage === TaskStage.Aborted) {
1810
+ child.abort(this.state.reason);
1811
+ }
1812
+ return this;
1813
+ }
1814
+ const childIndex = index ?? this.expectedCount;
1815
+ this.expectedCount = Math.max(this.expectedCount, childIndex + 1);
1816
+ this.children.set(child, childIndex);
1817
+ child.wait(
1818
+ (result) => this.handleChildSuccess(child, result, childIndex),
1819
+ (error) => this.handleChildError(child, error, childIndex)
1820
+ );
1821
+ return this;
1822
+ }
1823
+ /**
1824
+ * Finalize - signals that no more children will be added
1825
+ * If no children were added, resolves immediately
1826
+ */
1827
+ finalize() {
1828
+ if (this.isFinalized) return this;
1829
+ this.isFinalized = true;
1830
+ if (this.expectedCount === 0) {
1831
+ this.resolve(this.config.aggregate([]));
1832
+ }
1833
+ return this;
1834
+ }
1835
+ handleChildSuccess(child, result, index) {
1836
+ if (this.state.stage !== TaskStage.Pending) return;
1837
+ this.childResults[index] = result;
1838
+ this.completedCount++;
1839
+ this.children.delete(child);
1840
+ const progressValue = this.config.onChildComplete(
1841
+ this.completedCount,
1842
+ this.expectedCount,
1843
+ result,
1844
+ index
1845
+ );
1846
+ if (progressValue !== void 0) {
1847
+ this.progress(progressValue);
1848
+ }
1849
+ if (this.completedCount === this.expectedCount) {
1850
+ const finalResult = this.config.aggregate(this.childResults);
1851
+ this.resolve(finalResult);
1852
+ }
1853
+ }
1854
+ handleChildError(child, error, index) {
1855
+ if (this.state.stage !== TaskStage.Pending) return;
1856
+ this.children.delete(child);
1857
+ if (this.config.failFast) {
1858
+ for (const [otherChild] of this.children) {
1859
+ otherChild.abort("Sibling task failed");
1860
+ }
1861
+ this.children.clear();
1862
+ this.fail(error);
1863
+ } else {
1864
+ this.childResults[index] = void 0;
1865
+ this.completedCount++;
1866
+ if (this.completedCount === this.expectedCount) {
1867
+ const finalResult = this.config.aggregate(this.childResults);
1868
+ this.resolve(finalResult);
1869
+ }
1870
+ }
1871
+ }
1872
+ /**
1873
+ * Override abort to propagate to all children
1874
+ */
1875
+ abort(reason) {
1876
+ for (const [child] of this.children) {
1877
+ child.abort(reason);
1878
+ }
1879
+ this.children.clear();
1880
+ super.abort(reason);
1881
+ }
1882
+ /**
1883
+ * Override reject to abort all children
1884
+ */
1885
+ reject(reason) {
1886
+ for (const [child] of this.children) {
1887
+ child.abort(reason);
1888
+ }
1889
+ this.children.clear();
1890
+ super.reject(reason);
1891
+ }
1892
+ /**
1893
+ * Get count of pending children
1894
+ */
1895
+ getPendingCount() {
1896
+ return this.children.size;
1897
+ }
1898
+ /**
1899
+ * Get count of completed children
1900
+ */
1901
+ getCompletedCount() {
1902
+ return this.completedCount;
1903
+ }
1904
+ // ============================================================================
1905
+ // Static Factory Methods
1906
+ // ============================================================================
1907
+ /**
1908
+ * Gather results from an array of tasks (progress-friendly).
1909
+ * (Formerly: all)
1910
+ */
1911
+ static gather(tasks) {
1912
+ const compound = new CompoundTask({
1913
+ aggregate: (results) => results,
1914
+ onChildComplete: (completed, total) => ({ completed, total })
1915
+ });
1916
+ tasks.forEach((task, index) => compound.addChild(task, index));
1917
+ compound.finalize();
1918
+ return compound;
1919
+ }
1920
+ /**
1921
+ * Gather into a Record indexed by number.
1922
+ * (Formerly: allIndexed)
1923
+ */
1924
+ static gatherIndexed(tasks) {
1925
+ const compound = new CompoundTask({
1926
+ aggregate: (results) => {
1927
+ const record = {};
1928
+ results.forEach((result, index) => {
1929
+ record[index] = result;
1930
+ });
1931
+ return record;
1932
+ },
1933
+ onChildComplete: (_completed, _total, result, index) => ({ page: index, result })
1934
+ });
1935
+ tasks.forEach((task, index) => compound.addChild(task, index));
1936
+ compound.finalize();
1937
+ return compound;
1938
+ }
1939
+ /**
1940
+ * Gather with custom aggregation config.
1941
+ * (Formerly: from)
1942
+ */
1943
+ static gatherFrom(tasks, config) {
1944
+ const compound = new CompoundTask(config);
1945
+ tasks.forEach((task, index) => compound.addChild(task, index));
1946
+ compound.finalize();
1947
+ return compound;
1948
+ }
1949
+ /**
1950
+ * Resolve with the first successful child; abort the rest.
1951
+ * (Formerly: race)
1952
+ */
1953
+ static first(tasks) {
1954
+ let resolved = false;
1955
+ const compound = new CompoundTask({
1956
+ aggregate: (results) => results[0],
1957
+ failFast: false
1958
+ });
1959
+ compound["handleChildSuccess"] = (child, result) => {
1960
+ if (!resolved) {
1961
+ resolved = true;
1962
+ for (const [otherChild] of compound["children"]) {
1963
+ if (otherChild !== child) otherChild.abort("Race won by sibling");
1964
+ }
1965
+ compound.resolve(result);
1966
+ }
1967
+ };
1968
+ tasks.forEach((task, index) => compound.addChild(task, index));
1969
+ compound.finalize();
1970
+ return compound;
1971
+ }
1972
+ }
1785
1973
  function ignore() {
1786
1974
  }
1787
1975
  export {
1788
1976
  AllLogger,
1789
1977
  AppearanceMode,
1978
+ CompoundTask,
1790
1979
  ConsoleLogger,
1791
1980
  LevelLogger,
1792
1981
  LogLevel,
@@ -1844,6 +2033,7 @@ export {
1844
2033
  blendModeLabel,
1845
2034
  blendModeSelectOptions,
1846
2035
  blendModeToCss,
2036
+ blendModeValues,
1847
2037
  boundingRect,
1848
2038
  buildUserToDeviceMatrix,
1849
2039
  calculateAngle,