@tricoteuses/tisseuse 0.21.0 → 0.21.2

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.
Files changed (27) hide show
  1. package/README.md +39 -1
  2. package/dist/{html-jaUHsXKQ.js → html-DWNF_0Ek.js} +5264 -4923
  3. package/dist/index.js +84 -421
  4. package/dist/{resolver-CzmDH4S3.js → resolver-BBrU9oGB.js} +39 -28
  5. package/dist/server-f-legi.js +1 -1
  6. package/dist/server.js +971 -667
  7. package/dist/src/lib/extractors/links.d.ts +3 -1
  8. package/dist/src/lib/extractors/references.d.ts +4 -0
  9. package/dist/src/lib/index.d.ts +1 -1
  10. package/dist/src/lib/legi/canutes_root_cid_index.integration.test.d.ts +1 -0
  11. package/dist/src/lib/linkers/html.d.ts +3 -1
  12. package/dist/src/lib/linkers/markdown.d.ts +3 -1
  13. package/dist/src/lib/linkers/reference-mode.test.d.ts +1 -0
  14. package/dist/src/lib/server/databases/canutes_root_cid_index.d.ts +11 -0
  15. package/dist/src/lib/server/index.d.ts +2 -0
  16. package/dist/src/lib/server/jurisprudence_citations.d.ts +46 -0
  17. package/dist/src/lib/server/jurisprudence_citations.test.d.ts +1 -0
  18. package/dist/src/lib/server/jurisprudence_consultation.d.ts +55 -0
  19. package/dist/src/lib/server/jurisprudence_jade.d.ts +57 -0
  20. package/dist/src/lib/server/jurisprudence_jade.test.d.ts +1 -0
  21. package/dist/src/lib/server/jurisprudence_store.d.ts +36 -0
  22. package/dist/src/lib/server/jurisprudence_store.integration.test.d.ts +1 -0
  23. package/dist/src/lib/server/jurisprudence_store_closed.test.d.ts +1 -0
  24. package/dist/src/lib/text_parsers/parsers.d.ts +3 -0
  25. package/dist/src/scripts/alimenter_jurisprudence_pilote.d.ts +1 -0
  26. package/dist/src/scripts/configure_postgres_root_cid_index.d.ts +1 -0
  27. package/package.json +4 -1
@@ -1,4 +1,5 @@
1
1
  import { Sql } from 'postgres';
2
+ import { ReferenceParsingMode } from './references.js';
2
3
  import { LegiResolver } from '../legi/resolver.js';
3
4
  import { TextAstArticle, TextAstDivision, TextAstPosition, TextAstReference, TextAstText } from '../text_parsers/ast.js';
4
5
  import { FragmentPosition, FragmentReverseTransformation } from '../text_parsers/fragments.js';
@@ -146,7 +147,7 @@ type TextLinksIterationDiagnostics = {
146
147
  textLinkCount: number;
147
148
  textLinkMs: number;
148
149
  };
149
- export declare function extractTextLinks({ canutesDb, context, date, includeInternalArticleLinks, legiResolver: providedLegiResolver, logIgnoredReferencesTypes, logPartialReferences, logReferences, state: inputState, transformation, }: {
150
+ export declare function extractTextLinks({ canutesDb, context, date, includeInternalArticleLinks, legiResolver: providedLegiResolver, logIgnoredReferencesTypes, logPartialReferences, logReferences, parsingMode, state: inputState, transformation, }: {
150
151
  canutesDb?: Sql;
151
152
  context: TextParserContext;
152
153
  date: string;
@@ -155,6 +156,7 @@ export declare function extractTextLinks({ canutesDb, context, date, includeInte
155
156
  logIgnoredReferencesTypes?: boolean;
156
157
  logPartialReferences?: boolean;
157
158
  logReferences?: boolean;
159
+ parsingMode?: ReferenceParsingMode;
158
160
  /**
159
161
  * When given, state is modified by this generator, so that the callers
160
162
  * always has the latest state version (and can reuse it for the next article,
@@ -5,8 +5,12 @@ export type ExtractReferencesDiagnostics = {
5
5
  citationCount: number;
6
6
  fastPath: FastPathExtractDiagnostics;
7
7
  };
8
+ export declare const referenceParsingModes: readonly ["document", "references"];
9
+ export type ReferenceParsingMode = (typeof referenceParsingModes)[number];
8
10
  type ExtractReferencesOptions = {
9
11
  diagnostics?: ExtractReferencesDiagnostics;
12
+ /** Opt in to standalone references; document parsing remains the default. */
13
+ parsingMode?: ReferenceParsingMode;
10
14
  overlapWindowForCandidate?: (anchor: string) => number;
11
15
  /** Scoping metadata for flattened standalone quotations; never added to the AST. */
12
16
  onStandaloneCitationReference?: (reference: TextAstReference, citation: TextAstCitation) => void;
@@ -7,7 +7,7 @@ export { formatLongDate } from './dates.js';
7
7
  export { extractBillDefinitions } from './extractors/definitions.js';
8
8
  export { extractActionDirectivesFromHtml, extractActionDirectiveAstsFromText, extractActionDirectivesFromText, resolveActionDirectivesFromHtml, resolveActionDirectivesFromText, type ActionCitation, type ActionDirective, type ActionOperation, type ActionReplacement, type ActionTableTarget, type ResolvedActionDirective, } from './extractors/action_directives.js';
9
9
  export { extractTextLinks, iterReferenceLinks, type ArticleDefinition, type ArticleExternalLink, type ArticleInternalLink, type ArticleLink, type DefinitionOrLink, type DivisionExternalLink, type DivisionLink, type ExtractedLinkDb, type TextEuropeanLink, type TextExternalLink, type TextLink, type TextLinksParserState, } from './extractors/links.js';
10
- export { extractCitationReferences, extractReferences, extractReferencesWithOriginalTransformations, getExtractedReferences, getExtractedReferencesWithOriginalTransformations, } from './extractors/references.js';
10
+ export { extractCitationReferences, extractReferences, extractReferencesWithOriginalTransformations, getExtractedReferences, getExtractedReferencesWithOriginalTransformations, referenceParsingModes, type ReferenceParsingMode, } from './extractors/references.js';
11
11
  export { buildArticlePortionTreeFromHtml, extractPortionSelectors, getLegalPhraseTextBounds, getTableUnitNoteRanges, isArticlePortionStructuralStart, parseArticleSubdivisionMarker, resolvePortionSelector, type ArticlePortionArticle, type ArticlePortionDivision, type ArticlePortionItem, type ArticlePortionAlinea, type ArticlePortionPhrase, type ArticlePortionMatch, type ArticlePortionNode, type ArticleSubdivisionMarker, type PortionSelector, type PortionSelectorStep, } from './extractors/article_portions.js';
12
12
  export { addPositionsToTableOfContentsItems, getExtractedTableOfContentsFromTextBill, getTableOfContentsItems, walkTableOfContents, type TableOfContents, type TableOfContentsArticle, type TableOfContentsArticlePositioned, type TableOfContentsDivision, type TableOfContentsDivisionPositioned, type TableOfContentsItem, type TableOfContentsItemPositioned, type TableOfContentsPositioned, } from './extractors/table_of_contents.js';
13
13
  export { jsonReplacer } from './json.js';
@@ -1,11 +1,12 @@
1
1
  import { CanutesSql } from '../legi/canutes_sql.js';
2
2
  import { DefinitionOrLink, TextLinksParserState } from '../extractors/links.js';
3
+ import { ReferenceParsingMode } from '../extractors/references.js';
3
4
  import { LegiResolver } from '../legi/resolver.js';
4
5
  import { LinkType } from '../links.js';
5
6
  import { FragmentPosition } from '../text_parsers/fragments.js';
6
7
  import { TextParserContext } from '../text_parsers/parsers.js';
7
8
  import { Transformation } from '../text_parsers/transformers.js';
8
- export declare function addLinksToHtml({ canutesDb, excludedHtmlRanges, includeInternalArticleLinks, legiResolver: providedLegiResolver, date, html, linkBaseUrl, linkType, logIgnoredReferencesTypes, logPartialReferences, logReferences, onLink, previousContext, state, }: {
9
+ export declare function addLinksToHtml({ canutesDb, excludedHtmlRanges, includeInternalArticleLinks, legiResolver: providedLegiResolver, date, html, linkBaseUrl, linkType, logIgnoredReferencesTypes, logPartialReferences, logReferences, onLink, parsingMode, previousContext, state, }: {
9
10
  canutesDb?: CanutesSql;
10
11
  excludedHtmlRanges?: FragmentPosition[];
11
12
  includeInternalArticleLinks?: boolean;
@@ -18,6 +19,7 @@ export declare function addLinksToHtml({ canutesDb, excludedHtmlRanges, includeI
18
19
  logPartialReferences?: boolean;
19
20
  logReferences?: boolean;
20
21
  onLink?: (link: DefinitionOrLink, index: number) => Promise<boolean | void>;
22
+ parsingMode?: ReferenceParsingMode;
21
23
  previousContext?: TextParserContext;
22
24
  state?: TextLinksParserState;
23
25
  }): Promise<{
@@ -1,13 +1,15 @@
1
1
  import { CanutesSql } from '../legi/canutes_sql.js';
2
+ import { ReferenceParsingMode } from '../extractors/references.js';
2
3
  import { LegiResolver } from '../legi/resolver.js';
3
4
  import { LinkType } from '../links.js';
4
5
  import { TextParserContext } from '../text_parsers/parsers.js';
5
- export declare function addLinksToMarkdown({ canutesDb, legiResolver: providedLegiResolver, date, linkBaseUrl, linkType, previousContext, text, }: {
6
+ export declare function addLinksToMarkdown({ canutesDb, legiResolver: providedLegiResolver, date, linkBaseUrl, linkType, parsingMode, previousContext, text, }: {
6
7
  canutesDb?: CanutesSql;
7
8
  legiResolver?: LegiResolver;
8
9
  date: string;
9
10
  linkBaseUrl: string;
10
11
  linkType: LinkType;
12
+ parsingMode?: ReferenceParsingMode;
11
13
  previousContext?: TextParserContext;
12
14
  text: string;
13
15
  }): Promise<{
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,11 @@
1
+ import { Sql } from 'postgres';
2
+ export type CanutesRootCidIndexStatus = {
3
+ status: "missing" | "valid" | "invalid";
4
+ name: string | null;
5
+ };
6
+ /** SELECT-only; usable by readers, physical standbys and logical subscribers. */
7
+ export declare function inspectCanutesRootCidIndex(db: Sql): Promise<CanutesRootCidIndexStatus>;
8
+ /** Explicit administration only, outside transactions; never called by a reader/configure. */
9
+ export declare function ensureCanutesRootCidIndex(db: Sql, options?: {
10
+ repairInvalid?: boolean;
11
+ }): Promise<string>;
@@ -11,4 +11,6 @@ export { type LegiArticleInfo, LegiResolver, type LegiSectionInfo, type PreloadA
11
11
  export { buildAndInstallTextTitlesInfos, buildTextTitlesInfos, type BuildTextTitlesInfosProgress, type TextTitlesInfoRow, type TextTitlesInfos, } from '../legi/text_titles_infos.js';
12
12
  export { addPositionsToTableOfContentsFile, simplifiedHtmlBillFileToTableOfContentsFile, } from './tables_of_contents.js';
13
13
  export { createLegiResolver } from './legi/resolvers.js';
14
+ export { createJurisprudenceConsultation, type ConsultationDecision, type ConsultationJurisprudence, type IdentiteArticle, type IdentiteDecisionJade, } from './jurisprudence_consultation.js';
15
+ export { createJurisprudenceStore, initializeJurisprudenceStore, type PersistedJade, } from './jurisprudence_store.js';
14
16
  export { readTransformation, writeTransformation, } from './text_parsers/transformers.js';
@@ -0,0 +1,46 @@
1
+ import { TextTitlesInfos } from '../legi/text_titles_infos.js';
2
+ /** Identité d'une représentation JADE, distincte de l'identifiant documentaire. */
3
+ export interface DecisionSource {
4
+ dataset: "JADE";
5
+ path: string;
6
+ id: string;
7
+ revision: string;
8
+ publication: string;
9
+ dateDecision: string;
10
+ titre?: string;
11
+ texte: string;
12
+ }
13
+ export interface DecisionCitation {
14
+ mention: string;
15
+ position: {
16
+ start: number;
17
+ stop: number;
18
+ };
19
+ passage: string;
20
+ articleId: string | null;
21
+ candidats: string[];
22
+ /** La mention désigne un seul article et un seul code explicite. */
23
+ selectionPossible?: boolean;
24
+ redaction: "indéterminée";
25
+ origine: "indéterminée";
26
+ relation: "citation";
27
+ }
28
+ /**
29
+ * Première extraction conservatrice : seul un article avec code explicitement
30
+ * identifié peut être résolu. Le résolveur fournit une identité de disposition,
31
+ * pas une rédaction déterminée par date ; il ne reçoit jamais la date de décision.
32
+ * Les titres de codes doivent avoir été initialisés dans le parseur au préalable.
33
+ * Le texte fourni doit être la représentation adaptée aux droits de l'appelant.
34
+ */
35
+ export declare function extractDecisionCitations({ document, resolve, textTitlesInfos, }: {
36
+ document: DecisionSource;
37
+ textTitlesInfos?: TextTitlesInfos;
38
+ resolve: (reference: {
39
+ codeId: string;
40
+ numero: string;
41
+ }) => Promise<string[]>;
42
+ }): Promise<{
43
+ document: DecisionSource;
44
+ citations: DecisionCitation[];
45
+ perimetre: string;
46
+ }>;
@@ -0,0 +1,55 @@
1
+ import { default as postgres } from 'postgres';
2
+ import { DecisionCitation } from './jurisprudence_citations.js';
3
+ import { ArticleReferenceSelection } from './jurisprudence_jade.js';
4
+ /** Une représentation identifiée par son fonds et son chemin, pas seulement son id. */
5
+ export interface IdentiteDecisionJade {
6
+ dataset: "JADE";
7
+ path: string;
8
+ }
9
+ /** L'identifiant désigne un état précis du référentiel, pas une continuité. */
10
+ export interface IdentiteArticle {
11
+ articleId: string;
12
+ }
13
+ export interface ConsultationJurisprudence {
14
+ decision: {
15
+ dataset: "JADE";
16
+ path: string;
17
+ id: string;
18
+ revision: string;
19
+ titre: string;
20
+ titreNature: "source" | "référence";
21
+ publication: string;
22
+ dateDecision: string;
23
+ };
24
+ citations: DecisionCitation[];
25
+ couverture: {
26
+ perimetre: string;
27
+ traiteLe: string;
28
+ fraicheur: "non-verifiee";
29
+ };
30
+ referenceRevision: string;
31
+ selectionReference?: ArticleReferenceSelection;
32
+ selectionsReference?: ArticleReferenceSelection[];
33
+ }
34
+ export type ConsultationDecision = {
35
+ etat: "non-traite";
36
+ } | {
37
+ etat: "capture";
38
+ resultat: ConsultationJurisprudence;
39
+ };
40
+ /**
41
+ * Contrat serveur du pilote, sans autorisation ni activation publique implicite.
42
+ * L'appelant contrôle l'accès à la connexion et au schéma. La fraîcheur des
43
+ * captures n'est pas vérifiée. L'absence de citation ne prouve pas l'exhaustivité.
44
+ */
45
+ export declare function createJurisprudenceConsultation(sql: postgres.Sql, schema: string, options?: {
46
+ maxExtractionsArticle?: number;
47
+ }): Promise<{
48
+ parDecision(identite: IdentiteDecisionJade): Promise<ConsultationDecision>;
49
+ parArticle(identite: IdentiteArticle): Promise<{
50
+ resultats: ConsultationJurisprudence[];
51
+ resultatsPossibles: ConsultationJurisprudence[];
52
+ couverture: "inconnue";
53
+ fraicheur: "non-verifiee";
54
+ }>;
55
+ }>;
@@ -0,0 +1,57 @@
1
+ import { CanutesSql } from '../legi/canutes_sql.js';
2
+ import { TextTitlesInfos } from '../legi/text_titles_infos.js';
3
+ import { DecisionSource } from './jurisprudence_citations.js';
4
+ /** Données importées privées : ce contrat ne constitue pas une copie publique. */
5
+ export interface JadeInput {
6
+ dataset: string;
7
+ path: string;
8
+ id: string;
9
+ juridiction: string;
10
+ dateDec: string;
11
+ titre?: string | null;
12
+ data: unknown;
13
+ }
14
+ export declare class InvalidJadeSourceError extends Error {
15
+ }
16
+ export declare class StaleReferenceSelectionError extends Error {
17
+ }
18
+ export declare function adaptJadeDecision(input: JadeInput): DecisionSource;
19
+ /** Retourne tous les états candidats dans le référentiel observé, sans déduire
20
+ * ni continuité entre rédactions ni rédaction citée de la date de décision.
21
+ * L'appelant ne peut publier un résultat qu'après contrôle de fraîcheur. */
22
+ export declare function createHistoricalArticleResolver(sql: CanutesSql): ({ codeId, numero, }: {
23
+ codeId: string;
24
+ numero: string;
25
+ }) => Promise<string[]>;
26
+ export interface ArticleReferenceSelection {
27
+ dateReference: string;
28
+ articleId: string;
29
+ reference?: {
30
+ dataset: "JADE";
31
+ path: string;
32
+ revision: string;
33
+ position: {
34
+ start: number;
35
+ stop: number;
36
+ };
37
+ mention: string;
38
+ };
39
+ }
40
+ export type ArticleReferenceSelections = ArticleReferenceSelection | ArticleReferenceSelection[];
41
+ /** Capture cohérente, sans garantie de fraîcheur après ce snapshot. Ne pas
42
+ * utiliser ce résultat comme preuve persistée actuelle sans revalidation. */
43
+ export declare function extractJadeFromCanutesSnapshot(db: CanutesSql, path: string, selection?: ArticleReferenceSelections): Promise<{
44
+ selection?: ArticleReferenceSelections | undefined;
45
+ referenceRevision: string;
46
+ document: DecisionSource;
47
+ citations: import('./jurisprudence_citations.js').DecisionCitation[];
48
+ perimetre: string;
49
+ }>;
50
+ export declare function extractJadeDecisionCitations(input: JadeInput, resolve: (reference: {
51
+ codeId: string;
52
+ numero: string;
53
+ }) => Promise<string[]>, textTitlesInfos?: TextTitlesInfos): Promise<{
54
+ document: DecisionSource;
55
+ citations: import('./jurisprudence_citations.js').DecisionCitation[];
56
+ perimetre: string;
57
+ }>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,36 @@
1
+ import { default as postgres } from 'postgres';
2
+ import { extractJadeFromCanutesSnapshot, ArticleReferenceSelections } from './jurisprudence_jade.js';
3
+ type Extraction = Awaited<ReturnType<typeof extractJadeFromCanutesSnapshot>>;
4
+ export type PersistedJade = Extraction & {
5
+ traiteLe: string;
6
+ };
7
+ /** Alimentation bornée à une représentation explicitement identifiée. La
8
+ * migration est une opération séparée : aucun schéma n'est créé ici. */
9
+ export declare function alimenterJurisprudence(sql: postgres.Sql, schema: string, input: {
10
+ dataset: string;
11
+ path: string;
12
+ selection?: ArticleReferenceSelections;
13
+ }): Promise<PersistedJade>;
14
+ /** Stockage de pilote : le schéma et ses droits sont administrés par l'appelant.
15
+ * Les lectures servent la capture sans vérifier sa fraîcheur. */
16
+ export declare function initializeJurisprudenceStore(sql: postgres.Sql, schema: string): Promise<void>;
17
+ export declare function createJurisprudenceStore(sql: postgres.Sql, schema: string, options?: {
18
+ maxExtractionsArticle?: number;
19
+ }): Promise<{
20
+ capture(path: string, selection?: ArticleReferenceSelections): Promise<PersistedJade>;
21
+ /** Sert la dernière capture, qui peut être périmée. */
22
+ consultDecision(path: string): Promise<{
23
+ etat: "non-traite";
24
+ } | {
25
+ etat: "capture";
26
+ resultat: PersistedJade;
27
+ }>;
28
+ /** Consultation bornée des captures, sans contrôle de fraîcheur. */
29
+ consultArticle(articleId: string): Promise<{
30
+ resultats: PersistedJade[];
31
+ resultatsPossibles: PersistedJade[];
32
+ }>;
33
+ byDecision(path: string): Promise<PersistedJade | null>;
34
+ byArticle(articleId: string): Promise<PersistedJade[]>;
35
+ }>;
36
+ export {};
@@ -1,5 +1,6 @@
1
1
  import { TextAst, TextAstArticle, TextAstText, TextAstTextInfos, TextInfosByWordsTree } from './ast.js';
2
2
  import { FragmentPosition } from './fragments.js';
3
+ import { TextTitlesInfos } from '../legi/text_titles_infos.js';
3
4
  export type TextInfosConverter = (infos: TextAstTextInfos, context: TextParserContext) => TextAst | undefined;
4
5
  export type RegExpConverter = (match: RegExpExecArray, context: TextParserContext) => TextAst | undefined;
5
6
  export type TextAstConverter<T extends TextAst> = (ast: T, context: TextParserContext) => TextAst | undefined;
@@ -39,6 +40,8 @@ export declare class TextParserContext {
39
40
  length: number;
40
41
  usedInputs: TextTree | undefined;
41
42
  variables: Record<string, TextAst>;
43
+ /** Catalogue optionnel propre à cette analyse ; absent, utiliser le catalogue historique. */
44
+ textTitlesInfos?: TextTitlesInfos;
42
45
  constructor(input: string, offset?: number);
43
46
  position(): FragmentPosition;
44
47
  remaining(): string;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tricoteuses/tisseuse",
3
3
  "description": "Find links in/to French legislative documents",
4
- "version": "0.21.0",
4
+ "version": "0.21.2",
5
5
  "keywords": [
6
6
  "Assemblée nationale",
7
7
  "France",
@@ -59,6 +59,7 @@
59
59
  "associate:jorf:commissions": "tsx src/scripts/associate_jorf_textes_with_assemblee_commissions.ts",
60
60
  "associate:jorf:dossiers": "tsx src/scripts/associate_jorf_textes_with_dossiers_legislatifs_assemblee.ts",
61
61
  "audit:doctrinal-references": "tsx src/scripts/audit_doctrinal_references.ts",
62
+ "jurisprudence:pilote": "tsx src/scripts/alimenter_jurisprudence_pilote.ts",
62
63
  "audit:doctrinal-references:check": "tsx src/scripts/audit_doctrinal_references.ts --output /tmp/tisseuse-doctrinal-references-audit.json --baseline audits/doctrinal-references-baseline.json --fail-on-regression",
63
64
  "build": "vite build",
64
65
  "check": "tsc --noEmit",
@@ -66,6 +67,8 @@
66
67
  "configure:postgres:assemblee-triggers": "tsx src/scripts/configure_postgres_assemblee_document_triggers.ts",
67
68
  "configure:postgres:senat-triggers": "tsx src/scripts/configure_postgres_senat_document_triggers.ts",
68
69
  "configure:postgres:legi-resolver": "tsx src/scripts/configure_postgres_legi_resolver.ts",
70
+ "configure:postgres:legi-root-cid-index": "tsx src/scripts/configure_postgres_root_cid_index.ts",
71
+ "test:postgres:legi-root-cid-index": "vitest run src/lib/legi/canutes_root_cid_index.integration.test.ts",
69
72
  "warm:postgres:legi-titles": "tsx src/scripts/warm_canutes_text_titles_cache.ts",
70
73
  "test:postgres:legi-cache": "tsx src/scripts/test_canutes_titles_cache.ts",
71
74
  "profile:canutes-bill": "tsx src/scripts/profile_canutes_bill.ts",