@gtkx/codegen 1.1.0 → 1.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.
Files changed (149) hide show
  1. package/dist/analysis/descriptor-render.d.ts.map +1 -1
  2. package/dist/analysis/descriptor-render.js +14 -10
  3. package/dist/analysis/descriptor-render.js.map +1 -1
  4. package/dist/analysis/descriptor.d.ts +11 -5
  5. package/dist/analysis/descriptor.d.ts.map +1 -1
  6. package/dist/analysis/descriptor.js +25 -9
  7. package/dist/analysis/descriptor.js.map +1 -1
  8. package/dist/analysis/interface-conflicts.d.ts +3 -1
  9. package/dist/analysis/interface-conflicts.d.ts.map +1 -1
  10. package/dist/analysis/interface-conflicts.js +3 -8
  11. package/dist/analysis/interface-conflicts.js.map +1 -1
  12. package/dist/analysis/ts-type.d.ts +3 -2
  13. package/dist/analysis/ts-type.d.ts.map +1 -1
  14. package/dist/analysis/ts-type.js +16 -9
  15. package/dist/analysis/ts-type.js.map +1 -1
  16. package/dist/analysis/type-shape.d.ts +3 -2
  17. package/dist/analysis/type-shape.d.ts.map +1 -1
  18. package/dist/analysis/type-shape.js +2 -1
  19. package/dist/analysis/type-shape.js.map +1 -1
  20. package/dist/compile.d.ts +4 -5
  21. package/dist/compile.d.ts.map +1 -1
  22. package/dist/compile.js +56 -4
  23. package/dist/compile.js.map +1 -1
  24. package/dist/docs/api-reference.d.ts +2 -0
  25. package/dist/docs/api-reference.d.ts.map +1 -1
  26. package/dist/docs/api-reference.js +1 -1
  27. package/dist/docs/api-reference.js.map +1 -1
  28. package/dist/docs/pipeline.d.ts +1 -0
  29. package/dist/docs/pipeline.d.ts.map +1 -1
  30. package/dist/docs/pipeline.js +10 -3
  31. package/dist/docs/pipeline.js.map +1 -1
  32. package/dist/docs/symbol-page.d.ts.map +1 -1
  33. package/dist/docs/symbol-page.js +1 -3
  34. package/dist/docs/symbol-page.js.map +1 -1
  35. package/dist/fingerprint.d.ts +11 -5
  36. package/dist/fingerprint.d.ts.map +1 -1
  37. package/dist/fingerprint.js +22 -19
  38. package/dist/fingerprint.js.map +1 -1
  39. package/dist/gi.d.ts +1 -0
  40. package/dist/gi.d.ts.map +1 -1
  41. package/dist/gi.js +7 -2
  42. package/dist/gi.js.map +1 -1
  43. package/dist/gir/gir-path.d.ts +1 -1
  44. package/dist/gir/gir-path.js +1 -1
  45. package/dist/gir/gir-path.js.map +1 -1
  46. package/dist/gir/library.d.ts +5 -1
  47. package/dist/gir/library.d.ts.map +1 -1
  48. package/dist/gir/library.js +8 -1
  49. package/dist/gir/library.js.map +1 -1
  50. package/dist/gir/parse.d.ts.map +1 -1
  51. package/dist/gir/parse.js +4 -1
  52. package/dist/gir/parse.js.map +1 -1
  53. package/dist/gir/primitives.js +1 -1
  54. package/dist/gir/primitives.js.map +1 -1
  55. package/dist/khronos/args.d.ts.map +1 -1
  56. package/dist/khronos/args.js +8 -6
  57. package/dist/khronos/args.js.map +1 -1
  58. package/dist/khronos/render.d.ts.map +1 -1
  59. package/dist/khronos/render.js +8 -4
  60. package/dist/khronos/render.js.map +1 -1
  61. package/dist/runner.d.ts +2 -0
  62. package/dist/runner.d.ts.map +1 -1
  63. package/dist/runner.js +5 -3
  64. package/dist/runner.js.map +1 -1
  65. package/dist/staging.d.ts.map +1 -1
  66. package/dist/staging.js +1 -1
  67. package/dist/staging.js.map +1 -1
  68. package/dist/store/compile-store.d.ts +0 -1
  69. package/dist/store/compile-store.d.ts.map +1 -1
  70. package/dist/store/compile-store.js +7 -34
  71. package/dist/store/compile-store.js.map +1 -1
  72. package/dist/store/gi/callables.d.ts +1 -3
  73. package/dist/store/gi/callables.d.ts.map +1 -1
  74. package/dist/store/gi/callables.js +19 -4
  75. package/dist/store/gi/callables.js.map +1 -1
  76. package/dist/store/gi/class.d.ts.map +1 -1
  77. package/dist/store/gi/class.js +48 -9
  78. package/dist/store/gi/class.js.map +1 -1
  79. package/dist/store/gi/constant.js +1 -1
  80. package/dist/store/gi/constant.js.map +1 -1
  81. package/dist/store/gi/enum.d.ts.map +1 -1
  82. package/dist/store/gi/enum.js +2 -5
  83. package/dist/store/gi/enum.js.map +1 -1
  84. package/dist/store/gi/interface.js +2 -2
  85. package/dist/store/gi/interface.js.map +1 -1
  86. package/dist/store/gi/method.d.ts.map +1 -1
  87. package/dist/store/gi/method.js +4 -7
  88. package/dist/store/gi/method.js.map +1 -1
  89. package/dist/store/gi/property-accessor.d.ts +0 -3
  90. package/dist/store/gi/property-accessor.d.ts.map +1 -1
  91. package/dist/store/gi/property-accessor.js +15 -108
  92. package/dist/store/gi/property-accessor.js.map +1 -1
  93. package/dist/store/gi/record-constructor.js +3 -3
  94. package/dist/store/gi/record-constructor.js.map +1 -1
  95. package/dist/store/gi/record-field-accessor.d.ts.map +1 -1
  96. package/dist/store/gi/record-field-accessor.js +15 -3
  97. package/dist/store/gi/record-field-accessor.js.map +1 -1
  98. package/dist/store/gi/return-wrap.js +1 -1
  99. package/dist/store/gi/return-wrap.js.map +1 -1
  100. package/dist/store/gi/signal.d.ts.map +1 -1
  101. package/dist/store/gi/signal.js +25 -4
  102. package/dist/store/gi/signal.js.map +1 -1
  103. package/dist/store/jsx-store.d.ts.map +1 -1
  104. package/dist/store/jsx-store.js +0 -1
  105. package/dist/store/jsx-store.js.map +1 -1
  106. package/dist/store/store-fs.d.ts +0 -1
  107. package/dist/store/store-fs.d.ts.map +1 -1
  108. package/dist/store/store-fs.js +2 -7
  109. package/dist/store/store-fs.js.map +1 -1
  110. package/dist/xml.d.ts +1 -0
  111. package/dist/xml.d.ts.map +1 -1
  112. package/dist/xml.js +28 -1
  113. package/dist/xml.js.map +1 -1
  114. package/overrides/gobject/object.ts.ejs +2 -0
  115. package/package.json +3 -3
  116. package/src/analysis/descriptor-render.ts +19 -10
  117. package/src/analysis/descriptor.ts +43 -9
  118. package/src/analysis/interface-conflicts.ts +6 -8
  119. package/src/analysis/ts-type.ts +30 -11
  120. package/src/analysis/type-shape.ts +5 -2
  121. package/src/compile.ts +87 -6
  122. package/src/docs/api-reference.ts +3 -1
  123. package/src/docs/pipeline.ts +13 -7
  124. package/src/docs/symbol-page.ts +0 -4
  125. package/src/fingerprint.ts +31 -38
  126. package/src/gi.ts +9 -2
  127. package/src/gir/gir-path.ts +1 -1
  128. package/src/gir/library.ts +9 -1
  129. package/src/gir/parse.ts +6 -1
  130. package/src/gir/primitives.ts +1 -1
  131. package/src/khronos/args.ts +9 -6
  132. package/src/khronos/render.ts +8 -6
  133. package/src/runner.ts +7 -3
  134. package/src/staging.ts +1 -3
  135. package/src/store/compile-store.ts +7 -40
  136. package/src/store/gi/callables.ts +26 -7
  137. package/src/store/gi/class.ts +63 -7
  138. package/src/store/gi/constant.ts +1 -1
  139. package/src/store/gi/enum.ts +2 -6
  140. package/src/store/gi/interface.ts +2 -2
  141. package/src/store/gi/method.ts +4 -9
  142. package/src/store/gi/property-accessor.ts +22 -193
  143. package/src/store/gi/record-constructor.ts +3 -3
  144. package/src/store/gi/record-field-accessor.ts +18 -3
  145. package/src/store/gi/return-wrap.ts +1 -1
  146. package/src/store/gi/signal.ts +30 -4
  147. package/src/store/jsx-store.ts +0 -1
  148. package/src/store/store-fs.ts +3 -9
  149. package/src/xml.ts +43 -1
@@ -1 +1 @@
1
- {"version":3,"file":"store-fs.js","sourceRoot":"","sources":["../../src/store/store-fs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EACH,SAAS,EACT,UAAU,EACV,SAAS,EACT,YAAY,EACZ,UAAU,EACV,MAAM,EACN,WAAW,EACX,aAAa,GAChB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAqB,MAAM,eAAe,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAyClD,MAAM,cAAc,GAAG,KAAK,CAAC;AAC7B,MAAM,mBAAmB,GAAG,SAAS,CAAC;AAEtC,MAAM,aAAa,GAAG,CAAC,IAAY,EAAsC,EAAE,CAAC,CAAC;IACzE,KAAK,EAAE,KAAK,IAAI,OAAO;IACvB,OAAO,EAAE,KAAK,IAAI,KAAK;CAC1B,CAAC,CAAC;AAEH,MAAM,eAAe,GAAG,CAAC,SAAiB,EAAwC,EAAE,CAAC,CAAC;IAClF,QAAQ,EAAE,GAAG,SAAS,WAAW;IACjC,MAAM,EAAE,oBAAoB,SAAS,SAAS;CACjD,CAAC,CAAC;AAEH,MAAM,aAAa,GAAG,CAAC,KAAoB,EAAY,EAAE;IACrD,MAAM,QAAQ,GAAa;QACvB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,WAAW,EAAE,IAAI;QACjB,OAAO,EAAE,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE;KACpE,CAAC;IAEF,IAAI,KAAK,CAAC,gBAAgB,EAAE,CAAC;QACzB,QAAQ,CAAC,gBAAgB,GAAG,KAAK,CAAC,gBAAgB,CAAC;IACvD,CAAC;IAED,OAAO,QAAQ,CAAC;AACpB,CAAC,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,MAAwB,EAAQ,EAAE;IAClD,MAAM,GAAG,GAAG,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,GAAG,mBAAmB,EAAE,CAAC;IAE1D,IAAI,CAAC;QACD,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC5B,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;QAChC,eAAe,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,MAAM,iBAAiB,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACrD,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CAAC,GAAW,EAAE,MAAwB,EAAQ,EAAE;IACnE,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QAC9B,eAAe,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACrD,CAAC;IAED,YAAY,CAAC;QACT,QAAQ,EAAE,GAAG;QACb,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,WAAW,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI;QACjC,GAAG,CAAC,MAAM,CAAC,oBAAoB,KAAK,SAAS,IAAI,EAAE,oBAAoB,EAAE,MAAM,CAAC,oBAAoB,EAAE,CAAC;KAC1G,CAAC,CAAC;IAEH,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;IACvC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC;IAEvC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QACzB,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,YAAY,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IAC5D,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,CAAC,QAAgB,EAAE,QAAgB,EAAE,MAAc,EAAQ,EAAE;IACjF,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC1C,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAClD,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AACpC,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,CAAC,QAAgB,EAAE,UAAkB,EAAQ,EAAE;IACnE,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAClD,MAAM,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;AAC1E,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAAG,CAAC,QAAgB,EAAE,QAAkB,EAAQ,EAAE;IACpE,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AAC5F,CAAC,CAAC;AAEF,MAAM,SAAS,GAAG,CAAC,GAAW,EAAE,QAAgB,EAAQ,EAAE;IACtD,MAAM,QAAQ,GAAG,GAAG,QAAQ,MAAM,CAAC;IACnC,MAAM,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAEnD,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvB,UAAU,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACnC,CAAC;IAED,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC1B,MAAM,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACvD,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,CAAC,IAAe,EAAW,EAAE;IAC/C,IAAI,CAAC;QACD,OAAO,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACtE,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,KAAK,CAAC;IACjB,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,CAAC,IAAe,EAAQ,EAAE;IAC9C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC,IAAI,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1E,OAAO;IACX,CAAC;IAED,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;AACjD,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,QAAgB,EAAE,KAAc,EAAU,EAAE,CACnE,uCAAuC,QAAQ,KAAK,YAAY,CAAC,KAAK,CAAC,IAAI;IAC3E,kFAAkF;IAClF,MAAM,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAC;AAElD,MAAM,eAAe,GAAG,CAAC,QAAgB,EAAU,EAAE;IACjD,IAAI,CAAC;QACD,MAAM,GAAG,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QACvC,SAAS,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;QAE/B,OAAO,GAAG,CAAC;IACf,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1E,CAAC;AACL,CAAC,CAAC;AAEF,OAAO,EACH,aAAa,EACb,aAAa,EACb,eAAe,EACf,eAAe,EACf,UAAU,GAGb,CAAC","sourcesContent":["import { errorMessage } from \"@gtkx/utils\";\nimport {\n chmodSync,\n existsSync,\n mkdirSync,\n realpathSync,\n renameSync,\n rmSync,\n symlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { dirname, join, relative } from \"node:path\";\nimport { keepFailedProject, type SourceModule } from \"../compile.js\";\nimport { createStagingDir } from \"../staging.js\";\nimport { compileStore } from \"./compile-store.js\";\n\n/** Where one generated store is written and how it is reached. */\ntype StoreOptions = {\n /** Directory the generated package is written to, replaced atomically on each run. */\n storeDir: string;\n /** Path the store is symlinked at, which is the specifier's resolution target under `node_modules`. */\n linkDir: string;\n /** Version stamped on the store's `package.json`, taken from the dependency the store is generated for. */\n version: string;\n};\n\ntype StoreLink = Pick<StoreOptions, \"storeDir\" | \"linkDir\">;\n\ntype Manifest = {\n name: string;\n type: \"module\";\n version: string;\n sideEffects: true;\n exports: Record<string, unknown>;\n peerDependencies?: Record<string, string>;\n};\n\ntype ManifestInput = {\n name: string;\n version: string;\n exports: Record<string, unknown>;\n peerDependencies?: Record<string, string>;\n};\n\ntype RawFile = { relativePath: string; content: string };\n\ntype WriteStoreParams = {\n storeDir: string;\n linkDir: string;\n files: SourceModule[];\n manifest: Manifest;\n rawFiles?: RawFile[];\n requiresEnvReference?: boolean;\n};\n\nconst STORE_DIR_MODE = 0o755;\nconst FAILED_STORE_SUFFIX = \".failed\";\n\nconst subpathExport = (stem: string): { types: string; default: string } => ({\n types: `./${stem}.d.ts`,\n default: `./${stem}.js`,\n});\n\nconst namespaceBarrel = (directory: string): { fileName: string; source: string } => ({\n fileName: `${directory}/index.ts`,\n source: `export * from \"./${directory}.js\";\\n`,\n});\n\nconst buildManifest = (input: ManifestInput): Manifest => {\n const manifest: Manifest = {\n name: input.name,\n type: \"module\",\n version: input.version,\n sideEffects: true,\n exports: { \"./package.json\": \"./package.json\", ...input.exports },\n };\n\n if (input.peerDependencies) {\n manifest.peerDependencies = input.peerDependencies;\n }\n\n return manifest;\n};\n\nconst writeStore = (params: WriteStoreParams): void => {\n const tmp = createTempStore(params.storeDir);\n const keepAt = `${params.storeDir}${FAILED_STORE_SUFFIX}`;\n\n try {\n buildTempStore(tmp, params);\n swapStore(tmp, params.storeDir);\n ensureStoreLink(params);\n } catch (error) {\n throw keepFailedProject({ projectDir: tmp, keepAt, error });\n }\n\n rmSync(keepAt, { recursive: true, force: true });\n};\n\nconst buildTempStore = (tmp: string, params: WriteStoreParams): void => {\n for (const file of params.files) {\n writeSourceFile(tmp, file.fileName, file.source);\n }\n\n compileStore({\n storeDir: tmp,\n files: params.files,\n packageName: params.manifest.name,\n ...(params.requiresEnvReference !== undefined && { requiresEnvReference: params.requiresEnvReference }),\n });\n\n writePackageJson(tmp, params.manifest);\n const rawFiles = params.rawFiles ?? [];\n\n for (const raw of rawFiles) {\n writeFileSync(join(tmp, raw.relativePath), raw.content);\n }\n};\n\nconst writeSourceFile = (storeDir: string, fileName: string, source: string): void => {\n const filePath = join(storeDir, fileName);\n mkdirSync(dirname(filePath), { recursive: true });\n writeFileSync(filePath, source);\n};\n\nconst symlinkRelative = (linkPath: string, realTarget: string): void => {\n mkdirSync(dirname(linkPath), { recursive: true });\n rmSync(linkPath, { recursive: true, force: true });\n symlinkSync(relative(dirname(linkPath), realTarget), linkPath, \"dir\");\n};\n\nconst writePackageJson = (storeDir: string, manifest: Manifest): void => {\n writeFileSync(join(storeDir, \"package.json\"), `${JSON.stringify(manifest, null, 2)}\\n`);\n};\n\nconst swapStore = (tmp: string, storeDir: string): void => {\n const previous = `${storeDir}.old`;\n rmSync(previous, { recursive: true, force: true });\n\n if (existsSync(storeDir)) {\n renameSync(storeDir, previous);\n }\n\n renameSync(tmp, storeDir);\n rmSync(previous, { recursive: true, force: true });\n};\n\nconst isStoreLinked = (link: StoreLink): boolean => {\n try {\n return realpathSync(link.linkDir) === realpathSync(link.storeDir);\n } catch {\n return false;\n }\n};\n\nconst ensureStoreLink = (link: StoreLink): void => {\n if (!existsSync(join(link.storeDir, \"package.json\")) || isStoreLinked(link)) {\n return;\n }\n\n symlinkRelative(link.linkDir, link.storeDir);\n};\n\nconst storeWriteMessage = (storeDir: string, error: unknown): string =>\n `Cannot write the generated store to ${storeDir}: ${errorMessage(error)}. ` +\n \"Codegen writes the store into the node_modules the @gtkx packages resolve from, \" +\n `so ${dirname(storeDir)} has to be writable.`;\n\nconst createTempStore = (storeDir: string): string => {\n try {\n const tmp = createStagingDir(storeDir);\n chmodSync(tmp, STORE_DIR_MODE);\n\n return tmp;\n } catch (error) {\n throw new Error(storeWriteMessage(storeDir, error), { cause: error });\n }\n};\n\nexport {\n subpathExport,\n buildManifest,\n ensureStoreLink,\n namespaceBarrel,\n writeStore,\n type StoreOptions,\n type RawFile,\n};\n"]}
1
+ {"version":3,"file":"store-fs.js","sourceRoot":"","sources":["../../src/store/store-fs.ts"],"names":[],"mappings":"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","sourcesContent":["import { errorMessage } from \"@gtkx/utils\";\nimport {\n chmodSync,\n existsSync,\n mkdirSync,\n realpathSync,\n renameSync,\n rmSync,\n symlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { dirname, join, relative } from \"node:path\";\nimport { keepFailedProject, type SourceModule } from \"../compile.js\";\nimport { createStagingDir } from \"../staging.js\";\nimport { compileStore } from \"./compile-store.js\";\n\n/** Where one generated store is written and how it is reached. */\ntype StoreOptions = {\n /** Directory the generated package is written to, replaced atomically on each run. */\n storeDir: string;\n /** Path the store is symlinked at, which is the specifier's resolution target under `node_modules`. */\n linkDir: string;\n /** Version stamped on the store's `package.json`, taken from the dependency the store is generated for. */\n version: string;\n};\n\ntype StoreLink = Pick<StoreOptions, \"storeDir\" | \"linkDir\">;\n\ntype Manifest = {\n name: string;\n type: \"module\";\n version: string;\n sideEffects: true;\n exports: Record<string, unknown>;\n peerDependencies?: Record<string, string>;\n};\n\ntype ManifestInput = {\n name: string;\n version: string;\n exports: Record<string, unknown>;\n peerDependencies?: Record<string, string>;\n};\n\ntype RawFile = { relativePath: string; content: string };\n\ntype WriteStoreParams = {\n storeDir: string;\n linkDir: string;\n files: SourceModule[];\n manifest: Manifest;\n rawFiles?: RawFile[];\n};\n\nconst STORE_DIR_MODE = 0o755;\nconst FAILED_STORE_SUFFIX = \".failed\";\n\nconst subpathExport = (stem: string): { types: string; default: string } => ({\n types: `./${stem}.d.ts`,\n default: `./${stem}.js`,\n});\n\nconst namespaceBarrel = (directory: string): { fileName: string; source: string } => ({\n fileName: `${directory}/index.ts`,\n source: `export * from \"./${directory}.js\";\\n`,\n});\n\nconst buildManifest = (input: ManifestInput): Manifest => {\n const manifest: Manifest = {\n name: input.name,\n type: \"module\",\n version: input.version,\n sideEffects: true,\n exports: { \"./package.json\": \"./package.json\", ...input.exports },\n };\n\n if (input.peerDependencies) {\n manifest.peerDependencies = input.peerDependencies;\n }\n\n return manifest;\n};\n\nconst writeStore = (params: WriteStoreParams): void => {\n const tmp = createTempStore(params.storeDir);\n const keepAt = `${params.storeDir}${FAILED_STORE_SUFFIX}`;\n\n try {\n buildTempStore(tmp, params);\n swapStore(tmp, params.storeDir);\n ensureStoreLink(params);\n } catch (error) {\n throw keepFailedProject({ projectDir: tmp, keepAt, error });\n }\n\n rmSync(keepAt, { recursive: true, force: true });\n};\n\nconst buildTempStore = (tmp: string, params: WriteStoreParams): void => {\n writePackageJson(tmp, params.manifest);\n\n for (const file of params.files) {\n writeSourceFile(tmp, file.fileName, file.source);\n }\n\n compileStore({ storeDir: tmp, files: params.files, packageName: params.manifest.name });\n const rawFiles = params.rawFiles ?? [];\n\n for (const raw of rawFiles) {\n writeFileSync(join(tmp, raw.relativePath), raw.content);\n }\n};\n\nconst writeSourceFile = (storeDir: string, fileName: string, source: string): void => {\n const filePath = join(storeDir, fileName);\n mkdirSync(dirname(filePath), { recursive: true });\n writeFileSync(filePath, source);\n};\n\nconst symlinkRelative = (linkPath: string, realTarget: string): void => {\n mkdirSync(dirname(linkPath), { recursive: true });\n rmSync(linkPath, { recursive: true, force: true });\n symlinkSync(relative(dirname(linkPath), realTarget), linkPath, \"dir\");\n};\n\nconst writePackageJson = (storeDir: string, manifest: Manifest): void => {\n writeFileSync(join(storeDir, \"package.json\"), `${JSON.stringify(manifest, null, 2)}\\n`);\n};\n\nconst swapStore = (tmp: string, storeDir: string): void => {\n const previous = `${storeDir}.old`;\n rmSync(previous, { recursive: true, force: true });\n\n if (existsSync(storeDir)) {\n renameSync(storeDir, previous);\n }\n\n renameSync(tmp, storeDir);\n rmSync(previous, { recursive: true, force: true });\n};\n\nconst isStoreLinked = (link: StoreLink): boolean => {\n try {\n return realpathSync(link.linkDir) === realpathSync(link.storeDir);\n } catch {\n return false;\n }\n};\n\nconst ensureStoreLink = (link: StoreLink): void => {\n if (!existsSync(join(link.storeDir, \"package.json\")) || isStoreLinked(link)) {\n return;\n }\n\n symlinkRelative(link.linkDir, link.storeDir);\n};\n\nconst storeWriteMessage = (storeDir: string, error: unknown): string =>\n `Cannot write the generated store to ${storeDir}: ${errorMessage(error)}. ` +\n \"Codegen writes the store into the node_modules the @gtkx packages resolve from, \" +\n `so ${dirname(storeDir)} has to be writable.`;\n\nconst createTempStore = (storeDir: string): string => {\n try {\n const tmp = createStagingDir(storeDir);\n chmodSync(tmp, STORE_DIR_MODE);\n\n return tmp;\n } catch (error) {\n throw new Error(storeWriteMessage(storeDir, error), { cause: error });\n }\n};\n\nexport {\n subpathExport,\n buildManifest,\n ensureStoreLink,\n namespaceBarrel,\n writeStore,\n type StoreOptions,\n type RawFile,\n};\n"]}
package/dist/xml.d.ts CHANGED
@@ -3,6 +3,7 @@ type XmlFileInput = {
3
3
  parser: XMLParser;
4
4
  label: string;
5
5
  path: string;
6
+ malformedRemedy?: string;
6
7
  };
7
8
  declare const createXmlParser: (options: Partial<X2jOptions>) => XMLParser;
8
9
  declare const parseXmlFile: (input: XmlFileInput) => unknown;
package/dist/xml.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"xml.d.ts","sourceRoot":"","sources":["../src/xml.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,UAAU,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI7D,KAAK,YAAY,GAAG;IAChB,MAAM,EAAE,SAAS,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,QAAA,MAAM,eAAe,GAAI,SAAS,OAAO,CAAC,UAAU,CAAC,KAAG,SAOlD,CAAC;AA0CP,QAAA,MAAM,YAAY,GAAI,OAAO,YAAY,KAAG,OAS3C,CAAC;AAEF,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC"}
1
+ {"version":3,"file":"xml.d.ts","sourceRoot":"","sources":["../src/xml.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,UAAU,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI7D,KAAK,YAAY,GAAG;IAChB,MAAM,EAAE,SAAS,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAKF,QAAA,MAAM,eAAe,GAAI,SAAS,OAAO,CAAC,UAAU,CAAC,KAAG,SAOlD,CAAC;AAgFP,QAAA,MAAM,YAAY,GAAI,OAAO,YAAY,KAAG,OAS3C,CAAC;AAEF,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC"}
package/dist/xml.js CHANGED
@@ -2,6 +2,8 @@ import { errorMessage, isRecord } from "@gtkx/utils";
2
2
  import { XMLParser } from "fast-xml-parser";
3
3
  import { SyntaxValidator } from "fast-xml-validator";
4
4
  import { readFileSync } from "node:fs";
5
+ const HIGHEST_CONTROL_CODE = 0x1F;
6
+ const LEGAL_CONTROL_CODES = new Set([0x09, 0x0A, 0x0D]);
5
7
  const createXmlParser = (options) => new XMLParser({
6
8
  ignoreAttributes: false,
7
9
  attributeNamePrefix: "@_",
@@ -29,13 +31,38 @@ const positionSuffix = (error) => {
29
31
  }
30
32
  return ` (line ${String(line)}, column ${String(col)})`;
31
33
  };
34
+ const isIllegalControlCode = (code) => code <= HIGHEST_CONTROL_CODE && !LEGAL_CONTROL_CODES.has(code);
35
+ const escapedCode = (code) => `[U+${code.toString(16).toUpperCase().padStart(4, "0")}]`;
36
+ const escapeControlCodes = (text) => {
37
+ let escaped = "";
38
+ for (const character of text) {
39
+ const code = character.codePointAt(0) ?? 0;
40
+ escaped += isIllegalControlCode(code) ? escapedCode(code) : character;
41
+ }
42
+ return escaped;
43
+ };
44
+ const offendingLine = (xml, error) => {
45
+ const line = isRecord(error) ? error.line : undefined;
46
+ if (typeof line !== "number") {
47
+ return "";
48
+ }
49
+ const text = xml.split("\n")[line - 1];
50
+ if (text === undefined) {
51
+ return "";
52
+ }
53
+ return `\n ${escapeControlCodes(text.replace(/^[ \t]+/, "").replace(/\r$/, ""))}`;
54
+ };
55
+ const remedySuffix = (input, xml, error) => {
56
+ const remedy = input.malformedRemedy;
57
+ return remedy === undefined ? "" : `${offendingLine(xml, error)}\n${remedy}`;
58
+ };
32
59
  const assertWellFormed = (input, xml) => {
33
60
  try {
34
61
  SyntaxValidator.validate(xml);
35
62
  }
36
63
  catch (error) {
37
64
  throw new Error(`The ${input.label} at ${input.path} is not well-formed XML: ` +
38
- `${errorMessage(error)}${positionSuffix(error)}`, { cause: error });
65
+ `${errorMessage(error)}${positionSuffix(error)}${remedySuffix(input, xml, error)}`, { cause: error });
39
66
  }
40
67
  };
41
68
  const parseXmlFile = (input) => {
package/dist/xml.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"xml.js","sourceRoot":"","sources":["../src/xml.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAmB,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAQvC,MAAM,eAAe,GAAG,CAAC,OAA4B,EAAa,EAAE,CAChE,IAAI,SAAS,CAAC;IACV,gBAAgB,EAAE,KAAK;IACvB,mBAAmB,EAAE,IAAI;IACzB,mBAAmB,EAAE,KAAK;IAC1B,aAAa,EAAE,KAAK;IACpB,GAAG,OAAO;CACb,CAAC,CAAC;AAEP,MAAM,YAAY,GAAG,CAAC,KAAmB,EAAE,MAAc,EAAE,KAAc,EAAS,EAAE,CAChF,IAAI,KAAK,CAAC,UAAU,MAAM,QAAQ,KAAK,CAAC,KAAK,OAAO,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;AAEhH,MAAM,WAAW,GAAG,CAAC,KAAmB,EAAU,EAAE;IAChD,IAAI,CAAC;QACD,OAAO,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC5C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,MAAM,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;IAC7C,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,SAAS,GAAG,CAAC,IAAa,EAAE,GAAY,EAAW,EAAE,CACvD,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC;AAEjF,MAAM,cAAc,GAAG,CAAC,KAAc,EAAU,EAAE;IAC9C,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACnB,OAAO,EAAE,CAAC;IACd,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;IAE5B,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,CAAC;IACd,CAAC;IAED,OAAO,UAAU,MAAM,CAAC,IAAI,CAAC,YAAY,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;AAC5D,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAAG,CAAC,KAAmB,EAAE,GAAW,EAAQ,EAAE;IAChE,IAAI,CAAC;QACD,eAAe,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACX,OAAO,KAAK,CAAC,KAAK,OAAO,KAAK,CAAC,IAAI,2BAA2B;YAC9D,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,cAAc,CAAC,KAAK,CAAC,EAAE,EAChD,EAAE,KAAK,EAAE,KAAK,EAAE,CACnB,CAAC;IACN,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,CAAC,KAAmB,EAAW,EAAE;IAClD,MAAM,GAAG,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAC/B,gBAAgB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAE7B,IAAI,CAAC;QACD,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,MAAM,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IAC9C,CAAC;AACL,CAAC,CAAC;AAEF,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC","sourcesContent":["import { errorMessage, isRecord } from \"@gtkx/utils\";\nimport { type X2jOptions, XMLParser } from \"fast-xml-parser\";\nimport { SyntaxValidator } from \"fast-xml-validator\";\nimport { readFileSync } from \"node:fs\";\n\ntype XmlFileInput = {\n parser: XMLParser;\n label: string;\n path: string;\n};\n\nconst createXmlParser = (options: Partial<X2jOptions>): XMLParser =>\n new XMLParser({\n ignoreAttributes: false,\n attributeNamePrefix: \"@_\",\n parseAttributeValue: false,\n parseTagValue: false,\n ...options,\n });\n\nconst xmlFileError = (input: XmlFileInput, action: string, error: unknown): Error =>\n new Error(`Cannot ${action} the ${input.label} at ${input.path}: ${errorMessage(error)}`, { cause: error });\n\nconst readXmlFile = (input: XmlFileInput): string => {\n try {\n return readFileSync(input.path, \"utf8\");\n } catch (error) {\n throw xmlFileError(input, \"read\", error);\n }\n};\n\nconst isLocated = (line: unknown, col: unknown): boolean =>\n typeof line === \"number\" && typeof col === \"number\" && (line > 1 || col > 1);\n\nconst positionSuffix = (error: unknown): string => {\n if (!isRecord(error)) {\n return \"\";\n }\n\n const { line, col } = error;\n\n if (!isLocated(line, col)) {\n return \"\";\n }\n\n return ` (line ${String(line)}, column ${String(col)})`;\n};\n\nconst assertWellFormed = (input: XmlFileInput, xml: string): void => {\n try {\n SyntaxValidator.validate(xml);\n } catch (error) {\n throw new Error(\n `The ${input.label} at ${input.path} is not well-formed XML: ` +\n `${errorMessage(error)}${positionSuffix(error)}`,\n { cause: error },\n );\n }\n};\n\nconst parseXmlFile = (input: XmlFileInput): unknown => {\n const xml = readXmlFile(input);\n assertWellFormed(input, xml);\n\n try {\n return input.parser.parse(xml);\n } catch (error) {\n throw xmlFileError(input, \"parse\", error);\n }\n};\n\nexport { createXmlParser, parseXmlFile };\n"]}
1
+ {"version":3,"file":"xml.js","sourceRoot":"","sources":["../src/xml.ts"],"names":[],"mappings":"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","sourcesContent":["import { errorMessage, isRecord } from \"@gtkx/utils\";\nimport { type X2jOptions, XMLParser } from \"fast-xml-parser\";\nimport { SyntaxValidator } from \"fast-xml-validator\";\nimport { readFileSync } from \"node:fs\";\n\ntype XmlFileInput = {\n parser: XMLParser;\n label: string;\n path: string;\n malformedRemedy?: string;\n};\n\nconst HIGHEST_CONTROL_CODE = 0x1F;\nconst LEGAL_CONTROL_CODES: Set<number> = new Set([0x09, 0x0A, 0x0D]);\n\nconst createXmlParser = (options: Partial<X2jOptions>): XMLParser =>\n new XMLParser({\n ignoreAttributes: false,\n attributeNamePrefix: \"@_\",\n parseAttributeValue: false,\n parseTagValue: false,\n ...options,\n });\n\nconst xmlFileError = (input: XmlFileInput, action: string, error: unknown): Error =>\n new Error(`Cannot ${action} the ${input.label} at ${input.path}: ${errorMessage(error)}`, { cause: error });\n\nconst readXmlFile = (input: XmlFileInput): string => {\n try {\n return readFileSync(input.path, \"utf8\");\n } catch (error) {\n throw xmlFileError(input, \"read\", error);\n }\n};\n\nconst isLocated = (line: unknown, col: unknown): boolean =>\n typeof line === \"number\" && typeof col === \"number\" && (line > 1 || col > 1);\n\nconst positionSuffix = (error: unknown): string => {\n if (!isRecord(error)) {\n return \"\";\n }\n\n const { line, col } = error;\n\n if (!isLocated(line, col)) {\n return \"\";\n }\n\n return ` (line ${String(line)}, column ${String(col)})`;\n};\n\nconst isIllegalControlCode = (code: number): boolean =>\n code <= HIGHEST_CONTROL_CODE && !LEGAL_CONTROL_CODES.has(code);\n\nconst escapedCode = (code: number): string => `[U+${code.toString(16).toUpperCase().padStart(4, \"0\")}]`;\n\nconst escapeControlCodes = (text: string): string => {\n let escaped = \"\";\n\n for (const character of text) {\n const code = character.codePointAt(0) ?? 0;\n escaped += isIllegalControlCode(code) ? escapedCode(code) : character;\n }\n\n return escaped;\n};\n\nconst offendingLine = (xml: string, error: unknown): string => {\n const line = isRecord(error) ? error.line : undefined;\n\n if (typeof line !== \"number\") {\n return \"\";\n }\n\n const text = xml.split(\"\\n\")[line - 1];\n\n if (text === undefined) {\n return \"\";\n }\n\n return `\\n ${escapeControlCodes(text.replace(/^[ \\t]+/, \"\").replace(/\\r$/, \"\"))}`;\n};\n\nconst remedySuffix = (input: XmlFileInput, xml: string, error: unknown): string => {\n const remedy = input.malformedRemedy;\n\n return remedy === undefined ? \"\" : `${offendingLine(xml, error)}\\n${remedy}`;\n};\n\nconst assertWellFormed = (input: XmlFileInput, xml: string): void => {\n try {\n SyntaxValidator.validate(xml);\n } catch (error) {\n throw new Error(\n `The ${input.label} at ${input.path} is not well-formed XML: ` +\n `${errorMessage(error)}${positionSuffix(error)}${remedySuffix(input, xml, error)}`,\n { cause: error },\n );\n }\n};\n\nconst parseXmlFile = (input: XmlFileInput): unknown => {\n const xml = readXmlFile(input);\n assertWellFormed(input, xml);\n\n try {\n return input.parser.parse(xml);\n } catch (error) {\n throw xmlFileError(input, \"parse\", error);\n }\n};\n\nexport { createXmlParser, parseXmlFile };\n"]}
@@ -52,6 +52,7 @@ declare module "../gobject.js" {
52
52
  * @param callback Handler invoked on each emission.
53
53
  * @param isAfter Run the handler after the default handler rather than before it.
54
54
  * @returns The same object, so calls chain.
55
+ * @deprecated Since 1.2. Use `on` instead. Removed in v2.
55
56
  */
56
57
  addEventListener(sigName: string, callback: (...args: unknown[]) => unknown, isAfter?: boolean): Object;
57
58
 
@@ -61,6 +62,7 @@ declare module "../gobject.js" {
61
62
  * @param sigName Signal the handler was connected to.
62
63
  * @param callback The handler that was connected.
63
64
  * @returns The same object, so calls chain.
65
+ * @deprecated Since 1.2. Use `off` instead. Removed in v2.
64
66
  */
65
67
  removeEventListener(sigName: string, callback: (...args: unknown[]) => unknown): Object;
66
68
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gtkx/codegen",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Generates the typed GTKX bindings and API reference from GIR and OpenGL registry data",
5
5
  "keywords": [
6
6
  "gtkx",
@@ -58,8 +58,8 @@
58
58
  "fast-xml-parser": "^5.10.1",
59
59
  "fast-xml-validator": "^1.4.1",
60
60
  "typescript": "^6.0.3",
61
- "@gtkx/react": "1.1.0",
62
- "@gtkx/utils": "1.1.0"
61
+ "@gtkx/react": "1.2.0",
62
+ "@gtkx/utils": "1.2.0"
63
63
  },
64
64
  "scripts": {
65
65
  "release": "tsx ../../scripts/release-package.ts"
@@ -24,10 +24,12 @@ import { isRecordInout } from "../store/gi/param-marshal.js";
24
24
  import { computeRecordFieldSlots, recordInlineSize } from "../store/gi/record-layout.js";
25
25
  import { isValueMarshalable } from "../store/gi/value-marshalable.js";
26
26
  import {
27
+ type ArrayLayout,
27
28
  type ListDescriptorName,
28
29
  type Ownership,
29
30
  type ScalarDescriptorName,
30
31
  tArray,
32
+ tBiguint64,
31
33
  tBoxed,
32
34
  tByteArray,
33
35
  tCallback,
@@ -40,6 +42,7 @@ import {
40
42
  tHashTable,
41
43
  tInt32,
42
44
  tList,
45
+ tNumericByteArray,
43
46
  tObject,
44
47
  tRef,
45
48
  tScalar,
@@ -50,7 +53,7 @@ import {
50
53
  tUint64,
51
54
  tVoid,
52
55
  } from "./descriptor.js";
53
- import { carrayFor, isUnboundedArray, primitiveCategoryFor } from "./type-shape.js";
56
+ import { carrayFor, isByteSequence, isUnboundedArray, primitiveCategoryFor } from "./type-shape.js";
54
57
 
55
58
  type PrimaryReturnKind = "surfaced" | "void" | "skipped";
56
59
 
@@ -220,7 +223,7 @@ const listExpression = (
220
223
  const ownership = transferOwnership(transfer);
221
224
 
222
225
  if (type.flavor === "gbytearray") {
223
- return tByteArray(ownership);
226
+ return context.library.isByteArrayTyped ? tByteArray(ownership) : tNumericByteArray(ownership);
224
227
  }
225
228
 
226
229
  const element = renderDescriptor(context, type.element, deriveElementTransfer(transfer), indexOptions);
@@ -387,7 +390,7 @@ const primitiveExpression = (category: PrimitiveCategory, ownership: Ownership):
387
390
  }
388
391
 
389
392
  if (category === "pointer") {
390
- return tUint64;
393
+ return tBiguint64;
391
394
  }
392
395
 
393
396
  if (category === "gtype") {
@@ -703,7 +706,7 @@ const cursorArrayExpression = (
703
706
  context: ModuleContext,
704
707
  ref: CArrayType,
705
708
  transfer: ParameterTransfer,
706
- options: CursorArgIndexOptions,
709
+ options: CursorArgIndexOptions & { layout: ArrayLayout },
707
710
  ): string =>
708
711
  tCursorArray(
709
712
  elementExpression(context, ref, transfer, options),
@@ -712,9 +715,15 @@ const cursorArrayExpression = (
712
715
  lengthIndex: mapArgIndex(options, options.cursor.lengthIndex),
713
716
  },
714
717
  transferOwnership(transfer),
715
- inlineElementSize(context, ref, options.hasOutIndirection),
718
+ options.layout,
716
719
  );
717
720
 
721
+ const arrayLayout = (context: ModuleContext, ref: CArrayType, options: ArgIndexOptions): ArrayLayout => ({
722
+ elementSize: inlineElementSize(context, ref, options.hasOutIndirection),
723
+ isBytes:
724
+ context.library.isByteArrayTyped && !hasUnknownArrayLength(ref) && isByteSequence(context.library, ref),
725
+ });
726
+
718
727
  const arrayExpression = (
719
728
  context: ModuleContext,
720
729
  ref: CArrayType,
@@ -722,9 +731,10 @@ const arrayExpression = (
722
731
  options: ArgIndexOptions,
723
732
  ): string => {
724
733
  const { cursor } = options;
734
+ const layout = arrayLayout(context, ref, options);
725
735
 
726
736
  if (cursor !== undefined) {
727
- return cursorArrayExpression(context, ref, transfer, { ...options, cursor });
737
+ return cursorArrayExpression(context, ref, transfer, { ...options, cursor, layout });
728
738
  }
729
739
 
730
740
  if (hasUnknownArrayLength(ref)) {
@@ -733,17 +743,16 @@ const arrayExpression = (
733
743
 
734
744
  const ownership = transferOwnership(transfer);
735
745
  const element = elementExpression(context, ref, transfer, options);
736
- const size = inlineElementSize(context, ref, options.hasOutIndirection);
737
746
 
738
747
  if (ref.lengthParameterIndex !== undefined) {
739
- return tSizedArray(element, mapArgIndex(options, ref.lengthParameterIndex), ownership, size);
748
+ return tSizedArray(element, mapArgIndex(options, ref.lengthParameterIndex), ownership, layout);
740
749
  }
741
750
 
742
751
  if (ref.fixedSize !== undefined) {
743
- return tFixedArray(element, ref.fixedSize, ownership, size);
752
+ return tFixedArray(element, ref.fixedSize, ownership, layout);
744
753
  }
745
754
 
746
- return tArray(element, ownership, size);
755
+ return tArray(element, ownership, layout);
747
756
  };
748
757
 
749
758
  const elementPointerDepth = (elementCType: string | undefined, hasOutIndirection: boolean): number => {
@@ -87,6 +87,11 @@ type FundamentalOptions = {
87
87
 
88
88
  type ListDescriptorName = "list" | "slist" | "ptrArray" | "gArray";
89
89
 
90
+ type ArrayLayout = {
91
+ elementSize?: number | undefined;
92
+ isBytes: boolean;
93
+ };
94
+
90
95
  type BindArgs = {
91
96
  libExpr: string;
92
97
  symbolExpr: string;
@@ -156,6 +161,7 @@ const tUint8: string = T.uint8;
156
161
  const tUint32: string = T.uint32;
157
162
  const tInt32: string = T.int32;
158
163
  const tUint64: string = T.uint64;
164
+ const tBiguint64: string = T.biguint64;
159
165
  const tGtype: string = T.gtype;
160
166
  const tBuffer: string = T.buffer;
161
167
 
@@ -229,44 +235,69 @@ const tFlags = (lib: string, typeFnName: string, isSigned: boolean): string =>
229
235
 
230
236
  const tByteArray = (ownership: Ownership): string => call("byteArray", [sourceStringLiteral(ownership)]);
231
237
 
238
+ const tNumericByteArray = (ownership: Ownership): string =>
239
+ call("array", [
240
+ tUint8,
241
+ sourceStringLiteral("gbytearray"),
242
+ sourceStringLiteral(ownership),
243
+ ]);
244
+
232
245
  const tList = (name: ListDescriptorName, element: string, ownership: Ownership): string =>
233
246
  call(name, [element, sourceStringLiteral(ownership)]);
234
247
 
235
- const tArray = (element: string, ownership?: Ownership, elementSize?: number): string =>
248
+ const arrayLayoutArg = (ownership: Ownership | undefined, layout: ArrayLayout): string | undefined => {
249
+ if (ownership === undefined) {
250
+ return undefined;
251
+ }
252
+
253
+ const entries = [
254
+ layout.elementSize === undefined ? undefined : `elementSize: ${String(layout.elementSize)}`,
255
+ layout.isBytes ? "isBytes: true" : undefined,
256
+ ].filter((entry): entry is string => entry !== undefined);
257
+
258
+ return entries.length === 0 ? undefined : `{ ${entries.join(", ")} }`;
259
+ };
260
+
261
+ const tArray = (element: string, ownership: Ownership | undefined, layout: ArrayLayout): string =>
236
262
  call("array", [
237
263
  element,
238
264
  ownership === undefined ? undefined : sourceStringLiteral("array"),
239
265
  ownership === undefined ? undefined : sourceStringLiteral(ownership),
240
- elementSize === undefined ? undefined : `{ elementSize: ${String(elementSize)} }`,
266
+ arrayLayoutArg(ownership, layout),
241
267
  ]);
242
268
 
243
269
  const tSizedArray = (
244
270
  element: string,
245
271
  lengthIndex: number,
246
- ownership?: Ownership,
247
- elementSize?: number,
272
+ ownership: Ownership | undefined,
273
+ layout: ArrayLayout,
248
274
  ): string =>
249
275
  call("sizedArray", [
250
276
  element,
251
277
  String(lengthIndex),
252
278
  ownership === undefined ? undefined : sourceStringLiteral(ownership),
253
- elementSize === undefined ? undefined : String(elementSize),
279
+ arrayLayoutArg(ownership, layout),
254
280
  ]);
255
281
 
256
- const tCursorArray = (element: string, bounds: GirCursorBounds, ownership?: Ownership, elementSize?: number): string =>
282
+ const tCursorArray = (
283
+ element: string,
284
+ bounds: GirCursorBounds,
285
+ ownership: Ownership | undefined,
286
+ layout: ArrayLayout,
287
+ ): string =>
257
288
  call("cursorArray", [
258
289
  element,
259
290
  `{ baseParamIndex: ${String(bounds.baseIndex)}, sizeParamIndex: ${String(bounds.lengthIndex)} }`,
260
291
  ownership === undefined ? undefined : sourceStringLiteral(ownership),
261
- elementSize === undefined ? undefined : String(elementSize),
292
+ arrayLayoutArg(ownership, layout),
262
293
  ]);
263
294
 
264
- const tFixedArray = (element: string, length: number, ownership?: Ownership, elementSize?: number): string =>
295
+ const tFixedArray = (element: string, length: number, ownership: Ownership | undefined, layout: ArrayLayout): string =>
265
296
  call("fixedArray", [
266
297
  element,
267
298
  String(length),
268
299
  ownership === undefined ? undefined : sourceStringLiteral(ownership),
269
- elementSize === undefined ? undefined : String(elementSize),
300
+ arrayLayoutArg(ownership, layout),
270
301
  ]);
271
302
 
272
303
  const tCallback = (spec: CallbackSpecParts): string => {
@@ -296,6 +327,7 @@ export {
296
327
  tUint32,
297
328
  tInt32,
298
329
  tUint64,
330
+ tBiguint64,
299
331
  tGtype,
300
332
  tBuffer,
301
333
  tScalar,
@@ -310,6 +342,7 @@ export {
310
342
  tEnum,
311
343
  tFlags,
312
344
  tByteArray,
345
+ tNumericByteArray,
313
346
  tList,
314
347
  tArray,
315
348
  tSizedArray,
@@ -318,6 +351,7 @@ export {
318
351
  tCallback,
319
352
  tBind,
320
353
  tFn,
354
+ type ArrayLayout,
321
355
  type Ownership,
322
356
  type ScalarDescriptorName,
323
357
  type ListDescriptorName,
@@ -217,21 +217,19 @@ const prerequisiteConflicts = (library: Library, iface: GirClass, base: Resolved
217
217
  return names;
218
218
  };
219
219
 
220
- const omittedTypeRef = (typeRef: string, omissions: string[]): string => {
221
- if (omissions.length === 0) {
222
- return typeRef;
223
- }
224
-
225
- const keys = [...new Set(omissions)].map((name) => JSON.stringify(name)).join(" | ");
220
+ const omittedKeys = (omissions: string[]): string =>
221
+ [...new Set(omissions)].map((name) => JSON.stringify(name)).join(" | ");
226
222
 
227
- return `Omit<${typeRef}, ${keys}>`;
228
- };
223
+ const omittedTypeRef = (typeRef: string, omissions: string[]): string =>
224
+ omissions.length === 0 ? typeRef : `Omit<${typeRef}, ${omittedKeys(omissions)}>`;
229
225
 
230
226
  export {
227
+ areCallablesAssignable,
231
228
  type ClaimedMembers,
232
229
  claimInterfaceMembers,
233
230
  inheritedMembers,
234
231
  interfaceConflicts,
232
+ omittedKeys,
235
233
  omittedTypeRef,
236
234
  prerequisiteConflicts,
237
235
  };
@@ -12,6 +12,7 @@ import {
12
12
  type TypeId,
13
13
  } from "../gir/type-id.js";
14
14
  import { gtypeTsType } from "../store/gi/gtype-binding.js";
15
+ import { isByteSequence } from "./type-shape.js";
15
16
 
16
17
  type ReferenceName = {
17
18
  namespaceName: string;
@@ -21,11 +22,15 @@ type ReferenceName = {
21
22
  type TsTypeTarget = {
22
23
  containerStyle: "map" | "record";
23
24
  callbackType: string;
24
- shouldRenderByteArrayAsNumber: boolean;
25
+ byteArrayType: string;
25
26
  renderNamed: (resolved: GirType | undefined, name: ReferenceName) => string;
26
27
  renderGtype: () => string;
27
28
  };
28
29
 
30
+ const BYTE_ARRAY_TYPE = "Uint8Array";
31
+ const BYTE_ARRAY_INPUT_TYPE = "Uint8Array | number[]";
32
+ const NUMBER_ARRAY_TYPE = "number[]";
33
+
29
34
  const willEmitEntity = (type: EntityType): boolean => isEmittableEntity(type.value);
30
35
 
31
36
  const referenceName = (library: Library, ref: TypeId): ReferenceName | undefined => {
@@ -97,14 +102,14 @@ const renderContainerType = (
97
102
  };
98
103
 
99
104
  const renderSequenceType = (library: Library, target: TsTypeTarget, type: CArrayType | ListType): string => {
100
- if (type.kind === "list" && type.flavor === "gbytearray" && target.shouldRenderByteArrayAsNumber) {
101
- return "number[]";
102
- }
103
-
104
105
  if (type.kind === "carray" && hasUnknownArrayLength(type)) {
105
106
  return "number";
106
107
  }
107
108
 
109
+ if (isByteSequence(library, type)) {
110
+ return target.byteArrayType;
111
+ }
112
+
108
113
  return `${renderBaseType(library, target, type.element)}[]`;
109
114
  };
110
115
 
@@ -120,20 +125,34 @@ const renderNamedType = (
120
125
  return target.renderNamed(resolved, name);
121
126
  };
122
127
 
123
- const moduleTarget = (context: ModuleContext): TsTypeTarget => ({
128
+ const getByteArrayType = (library: Library): string =>
129
+ library.isByteArrayTyped ? BYTE_ARRAY_TYPE : NUMBER_ARRAY_TYPE;
130
+
131
+ const moduleTarget = (context: ModuleContext, byteArrayType: string): TsTypeTarget => ({
124
132
  containerStyle: "map",
125
133
  callbackType: "((...args: any[]) => any)",
126
- shouldRenderByteArrayAsNumber: true,
134
+ byteArrayType,
127
135
  renderNamed: (_resolved, name) => context.qualify(name.namespaceName, name.typeName),
128
136
  renderGtype: () => gtypeTsType(context),
129
137
  });
130
138
 
131
- const renderTsType = (context: ModuleContext, ref: TypeId | undefined, isNullable = false): string => {
132
- const base = renderBaseType(context.library, moduleTarget(context), ref);
139
+ const renderModuleType = (
140
+ context: ModuleContext,
141
+ ref: TypeId | undefined,
142
+ isNullable: boolean,
143
+ byteArrayType: string,
144
+ ): string => {
145
+ const base = renderBaseType(context.library, moduleTarget(context, byteArrayType), ref);
133
146
 
134
147
  return isNullable ? `${base} | null` : base;
135
148
  };
136
149
 
150
+ const renderTsType = (context: ModuleContext, ref: TypeId | undefined, isNullable = false): string =>
151
+ renderModuleType(context, ref, isNullable, getByteArrayType(context.library));
152
+
153
+ const renderParameterTsType = (context: ModuleContext, ref: TypeId | undefined, isNullable = false): string =>
154
+ renderModuleType(context, ref, isNullable, BYTE_ARRAY_INPUT_TYPE);
155
+
137
156
  const recordTypeTarget = (
138
157
  library: Library,
139
158
  renderNamedRef: (name: ReferenceName) => string,
@@ -142,7 +161,7 @@ const recordTypeTarget = (
142
161
  const target: TsTypeTarget = {
143
162
  containerStyle: "record",
144
163
  callbackType: "((...args: unknown[]) => unknown)",
145
- shouldRenderByteArrayAsNumber: false,
164
+ byteArrayType: getByteArrayType(library),
146
165
  renderNamed: (resolved, name) => {
147
166
  if (resolved?.kind === "alias") {
148
167
  return resolved.value.target === undefined
@@ -158,4 +177,4 @@ const recordTypeTarget = (
158
177
  return target;
159
178
  };
160
179
 
161
- export { renderBaseType, renderTsType, recordTypeTarget, type TsTypeTarget };
180
+ export { renderBaseType, renderParameterTsType, renderTsType, recordTypeTarget, type TsTypeTarget };
@@ -1,6 +1,6 @@
1
1
  import type { Library } from "../gir/library.js";
2
2
  import type { PrimitiveCategory } from "../gir/primitives.js";
3
- import type { CArrayType, TypeId } from "../gir/type-id.js";
3
+ import type { CArrayType, ListType, TypeId } from "../gir/type-id.js";
4
4
  import type { GirType } from "../gir/type.js";
5
5
 
6
6
  const resolvedTypeFor = (library: Library, ref: TypeId | undefined): GirType | undefined =>
@@ -21,4 +21,7 @@ const primitiveCategoryFor = (library: Library, ref: TypeId | undefined): Primit
21
21
  const isUnboundedArray = (type: CArrayType): boolean =>
22
22
  type.isZeroTerminated && type.lengthParameterIndex === undefined && type.fixedSize === undefined;
23
23
 
24
- export { carrayFor, isUnboundedArray, primitiveCategoryFor };
24
+ const isByteSequence = (library: Library, type: CArrayType | ListType): boolean =>
25
+ type.kind === "list" ? type.flavor === "gbytearray" : primitiveCategoryFor(library, type.element) === "uint8";
26
+
27
+ export { carrayFor, isByteSequence, isUnboundedArray, primitiveCategoryFor };