expressir 2.1.30 → 2.1.31

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 (107) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/docs.yml +98 -0
  3. data/.github/workflows/links.yml +100 -0
  4. data/.github/workflows/rake.yml +4 -0
  5. data/.github/workflows/release.yml +5 -0
  6. data/.github/workflows/validate_schemas.yml +1 -1
  7. data/.gitignore +3 -0
  8. data/.rubocop.yml +1 -1
  9. data/.rubocop_todo.yml +244 -39
  10. data/Gemfile +2 -1
  11. data/README.adoc +621 -54
  12. data/docs/Gemfile +12 -0
  13. data/docs/_config.yml +141 -0
  14. data/docs/_guides/changes/changes-format.adoc +778 -0
  15. data/docs/_guides/changes/importing-eengine.adoc +898 -0
  16. data/docs/_guides/changes/index.adoc +396 -0
  17. data/docs/_guides/changes/programmatic-usage.adoc +1038 -0
  18. data/docs/_guides/changes/validating-changes.adoc +681 -0
  19. data/docs/_guides/cli/benchmark-performance.adoc +834 -0
  20. data/docs/_guides/cli/coverage-analysis.adoc +921 -0
  21. data/docs/_guides/cli/format-schemas.adoc +547 -0
  22. data/docs/_guides/cli/index.adoc +8 -0
  23. data/docs/_guides/cli/managing-changes.adoc +927 -0
  24. data/docs/_guides/cli/validate-ascii.adoc +645 -0
  25. data/docs/_guides/cli/validate-schemas.adoc +534 -0
  26. data/docs/_guides/index.adoc +165 -0
  27. data/docs/_guides/ler/creating-packages.adoc +664 -0
  28. data/docs/_guides/ler/index.adoc +305 -0
  29. data/docs/_guides/ler/loading-packages.adoc +707 -0
  30. data/docs/_guides/ler/package-formats.adoc +748 -0
  31. data/docs/_guides/ler/querying-packages.adoc +826 -0
  32. data/docs/_guides/ler/validating-packages.adoc +750 -0
  33. data/docs/_guides/liquid/basic-templates.adoc +813 -0
  34. data/docs/_guides/liquid/documentation-generation.adoc +1042 -0
  35. data/docs/_guides/liquid/drops-reference.adoc +829 -0
  36. data/docs/_guides/liquid/filters-and-tags.adoc +912 -0
  37. data/docs/_guides/liquid/index.adoc +468 -0
  38. data/docs/_guides/manifests/creating-manifests.adoc +483 -0
  39. data/docs/_guides/manifests/index.adoc +307 -0
  40. data/docs/_guides/manifests/resolving-manifests.adoc +557 -0
  41. data/docs/_guides/manifests/validating-manifests.adoc +713 -0
  42. data/docs/_guides/ruby-api/formatting-schemas.adoc +605 -0
  43. data/docs/_guides/ruby-api/index.adoc +257 -0
  44. data/docs/_guides/ruby-api/parsing-files.adoc +421 -0
  45. data/docs/_guides/ruby-api/search-engine.adoc +609 -0
  46. data/docs/_guides/ruby-api/working-with-repository.adoc +577 -0
  47. data/docs/_pages/data-model.adoc +665 -0
  48. data/docs/_pages/express-language.adoc +506 -0
  49. data/docs/_pages/getting-started.adoc +414 -0
  50. data/docs/_pages/index.adoc +116 -0
  51. data/docs/_pages/introduction.adoc +256 -0
  52. data/docs/_pages/ler-packages.adoc +837 -0
  53. data/docs/_pages/parsers.adoc +683 -0
  54. data/docs/_pages/schema-manifests.adoc +431 -0
  55. data/docs/_references/index.adoc +228 -0
  56. data/docs/_tutorials/creating-ler-package.adoc +735 -0
  57. data/docs/_tutorials/documentation-coverage.adoc +795 -0
  58. data/docs/_tutorials/index.adoc +221 -0
  59. data/docs/_tutorials/liquid-templates.adoc +806 -0
  60. data/docs/_tutorials/parsing-your-first-schema.adoc +522 -0
  61. data/docs/_tutorials/querying-schemas.adoc +751 -0
  62. data/docs/_tutorials/working-with-multiple-schemas.adoc +676 -0
  63. data/docs/index.adoc +242 -0
  64. data/docs/lychee.toml +84 -0
  65. data/examples/demo_ler_usage.sh +86 -0
  66. data/examples/ler/README.md +111 -0
  67. data/examples/ler/simple_example.ler +0 -0
  68. data/examples/ler/simple_schema.exp +33 -0
  69. data/examples/ler_build.rb +75 -0
  70. data/examples/ler_cli.rb +79 -0
  71. data/examples/ler_demo_complete.rb +276 -0
  72. data/examples/ler_query.rb +91 -0
  73. data/examples/ler_query_examples.rb +305 -0
  74. data/examples/ler_stats.rb +81 -0
  75. data/examples/phase3_demo.rb +159 -0
  76. data/examples/query_demo_simple.rb +131 -0
  77. data/expressir.gemspec +2 -0
  78. data/lib/expressir/cli.rb +12 -4
  79. data/lib/expressir/commands/manifest.rb +427 -0
  80. data/lib/expressir/commands/package.rb +1274 -0
  81. data/lib/expressir/commands/validate.rb +70 -37
  82. data/lib/expressir/commands/validate_ascii.rb +607 -0
  83. data/lib/expressir/commands/validate_load.rb +88 -0
  84. data/lib/expressir/express/formatter.rb +5 -1
  85. data/lib/expressir/express/formatters/remark_item_formatter.rb +25 -0
  86. data/lib/expressir/express/parser.rb +33 -0
  87. data/lib/expressir/manifest/resolver.rb +213 -0
  88. data/lib/expressir/manifest/validator.rb +195 -0
  89. data/lib/expressir/model/declarations/entity.rb +6 -0
  90. data/lib/expressir/model/dependency_resolver.rb +270 -0
  91. data/lib/expressir/model/indexes/entity_index.rb +103 -0
  92. data/lib/expressir/model/indexes/reference_index.rb +148 -0
  93. data/lib/expressir/model/indexes/type_index.rb +149 -0
  94. data/lib/expressir/model/interface_validator.rb +384 -0
  95. data/lib/expressir/model/repository.rb +400 -5
  96. data/lib/expressir/model/repository_validator.rb +295 -0
  97. data/lib/expressir/model/search_engine.rb +525 -0
  98. data/lib/expressir/model.rb +4 -94
  99. data/lib/expressir/package/builder.rb +200 -0
  100. data/lib/expressir/package/metadata.rb +81 -0
  101. data/lib/expressir/package/reader.rb +165 -0
  102. data/lib/expressir/schema_manifest.rb +11 -1
  103. data/lib/expressir/version.rb +1 -1
  104. data/lib/expressir.rb +15 -2
  105. metadata +114 -4
  106. data/docs/benchmarking.adoc +0 -107
  107. data/docs/liquid_drops.adoc +0 -1547
@@ -0,0 +1,735 @@
1
+ ---
2
+ title: Creating LER Packages
3
+ nav_order: 4
4
+ ---
5
+
6
+ == Creating LER Packages
7
+
8
+ === Prerequisites
9
+
10
+ Before starting this tutorial, ensure you have:
11
+
12
+ * Completed link:working-with-multiple-schemas.html[Working with Multiple Schemas]
13
+ * Understanding of EXPRESS schema dependencies
14
+ * Multiple EXPRESS schema files to package
15
+ * Expressir installed with CLI access
16
+
17
+ === Learning Objectives
18
+
19
+ By the end of this tutorial, you will be able to:
20
+
21
+ * Understand what LER packages are and their benefits
22
+ * Create LER packages from EXPRESS schemas
23
+ * Configure packaging options for different use cases
24
+ * Load and query LER packages
25
+ * Validate package integrity
26
+ * Optimize packages for performance
27
+
28
+ === What You'll Build
29
+
30
+ You'll create a distributable LER package from the multi-schema product catalog system, making it easy to share and use without re-parsing.
31
+
32
+ === Step 1: Understanding LER Packages
33
+
34
+ ==== What is a LER Package?
35
+
36
+ LutaML EXPRESS Repository (LER) is a distributable package format that:
37
+
38
+ * **Bundles all schemas** into a single `.ler` file
39
+ * **Pre-builds indexes** for fast entity/type lookups
40
+ * **Resolves references** so they're ready to use
41
+ * **Loads instantly** (<500ms vs 10+ seconds parsing)
42
+
43
+ ==== Why Use LER Packages?
44
+
45
+ **Performance**::
46
+ Loading a pre-parsed package is 20-50x faster than parsing
47
+
48
+ **Distribution**::
49
+ One file contains everything needed
50
+
51
+ **Consistency**::
52
+ Everyone uses the same parsed result
53
+
54
+ **Production-ready**::
55
+ No parsing overhead in production
56
+
57
+ ==== LER Package Structure
58
+
59
+ [source]
60
+ ----
61
+ activity.ler (ZIP archive)
62
+ ├── metadata.yaml # Package info
63
+ ├── repository.marshal # Serialized schemas
64
+ ├── entity_index.marshal # Fast entity lookups
65
+ ├── type_index.marshal # Fast type lookups
66
+ ├── reference_index.marshal # Reference mappings
67
+ ├── manifest.yaml # Schema list
68
+ └── express_files/ # Original EXPRESS files
69
+ ├── schema1.exp
70
+ └── schema2.exp
71
+ ----
72
+
73
+ === Step 2: Create Sample Schemas
74
+
75
+ First, let's create schemas to package.
76
+
77
+ ==== Create `base_schema.exp`
78
+
79
+ [source,express]
80
+ ----
81
+ SCHEMA base_schema;
82
+
83
+ TYPE identifier = STRING;
84
+ END_TYPE;
85
+
86
+ TYPE label = STRING;
87
+ END_TYPE;
88
+
89
+ ENTITY person;
90
+ name : label;
91
+ email : OPTIONAL STRING;
92
+ END_ENTITY;
93
+
94
+ ENTITY organization;
95
+ org_name : label;
96
+ employees : SET [0:?] OF person;
97
+ END_ENTITY;
98
+
99
+ END_SCHEMA;
100
+ ----
101
+
102
+ ==== Create `product_schema.exp`
103
+
104
+ [source,express]
105
+ ----
106
+ SCHEMA product_schema;
107
+
108
+ REFERENCE FROM base_schema (identifier, label, person, organization);
109
+
110
+ ENTITY product;
111
+ id : identifier;
112
+ name : label;
113
+ price : REAL;
114
+ manufacturer : organization;
115
+ END_ENTITY;
116
+
117
+ ENTITY product_category;
118
+ category_name : label;
119
+ products : SET [0:?] OF product;
120
+ END_ENTITY;
121
+
122
+ END_SCHEMA;
123
+ ----
124
+
125
+ === Step 3: Create Your First Package
126
+
127
+ ==== Using the CLI
128
+
129
+ The simplest way to create a package:
130
+
131
+ [source,bash]
132
+ ----
133
+ # Create package from schema files
134
+ expressir package build base_schema.exp product_schema.exp catalog.ler
135
+
136
+ # With metadata
137
+ expressir package build base_schema.exp product_schema.exp catalog.ler \
138
+ --name "Product Catalog" \
139
+ --version "1.0.0" \
140
+ --description "Sample product catalog schemas"
141
+ ----
142
+
143
+ **Expected output**:
144
+ [source]
145
+ ----
146
+ ✓ Parsing base_schema.exp
147
+ ✓ Parsing product_schema.exp
148
+ ✓ Resolving references
149
+ ✓ Building indexes
150
+ ✓ Creating package catalog.ler
151
+
152
+ Package created successfully!
153
+ Size: 45 KB
154
+ Schemas: 2
155
+ Entities: 4
156
+ Types: 2
157
+ ----
158
+
159
+ ==== Verify the Package
160
+
161
+ [source,bash]
162
+ ----
163
+ # Show package information
164
+ expressir package info catalog.ler
165
+ ----
166
+
167
+ **Output**:
168
+ [source]
169
+ ----
170
+ Package Information
171
+ ==================================================
172
+ Name: Product Catalog
173
+ Version: 1.0.0
174
+ Description: Sample product catalog schemas
175
+ Created: 2025-11-28T03:00:00Z
176
+
177
+ Configuration
178
+ --------------------------------------------------
179
+ Express mode: include_all
180
+ Resolution mode: resolved
181
+ Serialization format: marshal
182
+
183
+ Statistics
184
+ --------------------------------------------------
185
+ Total schemas: 2
186
+ Total entities: 4
187
+ Total types: 2
188
+ Total functions: 0
189
+ Total rules: 0
190
+ Total procedures: 0
191
+ ----
192
+
193
+ === Step 4: Package Configuration Options
194
+
195
+ ==== Express Mode
196
+
197
+ Controls how EXPRESS files are bundled:
198
+
199
+ **include_all** (default)::
200
+ Includes original EXPRESS files in package
201
+ +
202
+ [source,bash]
203
+ ----
204
+ expressir package build schema.exp output.ler --express-mode include_all
205
+ ----
206
+
207
+ **allow_external**::
208
+ References external EXPRESS files (smaller package)
209
+ +
210
+ [source,bash]
211
+ ----
212
+ expressir package build schema.exp output.ler --express-mode allow_external
213
+ ----
214
+
215
+ ==== Resolution Mode
216
+
217
+ Controls reference resolution:
218
+
219
+ **resolved** (default)::
220
+ Pre-resolves all references for faster loading
221
+ +
222
+ [source,bash]
223
+ ----
224
+ expressir package build schema.exp output.ler --resolution-mode resolved
225
+ ----
226
+
227
+ **bare**::
228
+ Does not pre-resolve (smaller but slower to load)
229
+ +
230
+ [source,bash]
231
+ ----
232
+ expressir package build schema.exp output.ler --resolution-mode bare
233
+ ----
234
+
235
+ ==== Serialization Format
236
+
237
+ Controls internal data format:
238
+
239
+ **marshal** (default)::
240
+ Ruby's native format, fastest
241
+ +
242
+ [source,bash]
243
+ ----
244
+ expressir package build schema.exp output.ler --serialization-format marshal
245
+ ----
246
+
247
+ **yaml**::
248
+ Human-readable, cross-platform
249
+ +
250
+ [source,bash]
251
+ ----
252
+ expressir package build schema.exp output.ler --serialization-format yaml
253
+ ----
254
+
255
+ **json**::
256
+ Standard format, good compatibility
257
+ +
258
+ [source,bash]
259
+ ----
260
+ expressir package build schema.exp output.ler --serialization-format json
261
+ ----
262
+
263
+ === Step 5: Build Optimized Packages
264
+
265
+ ==== Production Package (Fastest)
266
+
267
+ [source,bash]
268
+ ----
269
+ expressir package build base_schema.exp product_schema.exp production.ler \
270
+ --name "Production Catalog" \
271
+ --version "1.0.0" \
272
+ --express-mode include_all \
273
+ --resolution-mode resolved \
274
+ --serialization-format marshal \
275
+ --validate
276
+ ----
277
+
278
+ **When to use**: Production deployments where speed is critical
279
+
280
+ ==== Portable Package (Cross-Platform)
281
+
282
+ [source,bash]
283
+ ----
284
+ expressir package build base_schema.exp product_schema.exp portable.ler \
285
+ --name "Portable Catalog" \
286
+ --version "1.0.0" \
287
+ --serialization-format json \
288
+ --validate
289
+ ----
290
+
291
+ **When to use**: Sharing across different Ruby versions or platforms
292
+
293
+ ==== Debug Package (Human-Readable)
294
+
295
+ [source,bash]
296
+ ----
297
+ expressir package build base_schema.exp product_schema.exp debug.ler \
298
+ --name "Debug Catalog" \
299
+ --version "1.0.0" \
300
+ --serialization-format yaml \
301
+ --validate
302
+ ----
303
+
304
+ **When to use**: Development and debugging
305
+
306
+ === Step 6: Load and Use Packages
307
+
308
+ ==== Load with CLI
309
+
310
+ [source,bash]
311
+ ----
312
+ # List all entities
313
+ expressir package list catalog.ler
314
+
315
+ # List entities in specific schema
316
+ expressir package list catalog.ler --schema product_schema
317
+
318
+ # Search for entities
319
+ expressir package search catalog.ler "product"
320
+ ----
321
+
322
+ ==== Load with Ruby API
323
+
324
+ Create `use_package.rb`:
325
+
326
+ [source,ruby]
327
+ ----
328
+ require 'expressir'
329
+
330
+ # Load package
331
+ repo = Expressir::Model::Repository.from_package('catalog.ler')
332
+
333
+ puts "Loaded package:"
334
+ puts " Schemas: #{repo.schemas.size}"
335
+ puts " Total entities: #{repo.schemas.sum { |s| s.entities.size }}"
336
+
337
+ # Access schemas
338
+ repo.schemas.each do |schema|
339
+ puts "\n#{schema.id}:"
340
+ schema.entities.each do |entity|
341
+ puts " - #{entity.id}"
342
+ end
343
+ end
344
+ ----
345
+
346
+ Run it:
347
+
348
+ [source,bash]
349
+ ----
350
+ ruby use_package.rb
351
+ ----
352
+
353
+ **Output**:
354
+ [source]
355
+ ----
356
+ Loaded package:
357
+ Schemas: 2
358
+ Total entities: 4
359
+
360
+ base_schema:
361
+ - person
362
+ - organization
363
+
364
+ product_schema:
365
+ - product
366
+ - product_category
367
+ ----
368
+
369
+ === Step 7: Query Package Contents
370
+
371
+ ==== Using the Search Engine
372
+
373
+ Create `query_package.rb`:
374
+
375
+ [source,ruby]
376
+ ----
377
+ require 'expressir'
378
+
379
+ # Load package
380
+ repo = Expressir::Model::Repository.from_package('catalog.ler')
381
+
382
+ # Create search engine
383
+ search = Expressir::Model::SearchEngine.new(repo)
384
+
385
+ # List all entities
386
+ puts "All entities:"
387
+ entities = search.list(type: 'entity')
388
+ entities.each do |e|
389
+ puts " #{e[:schema]}.#{e[:id]}"
390
+ end
391
+
392
+ # Search by pattern
393
+ puts "\nEntities starting with 'product':"
394
+ results = search.search(pattern: 'product*', type: 'entity')
395
+ results.each do |r|
396
+ puts " #{r[:path]}"
397
+ end
398
+
399
+ # Find specific entity
400
+ puts "\nFinding 'product_category':"
401
+ result = search.search(pattern: 'product_category', type: 'entity', exact: true)
402
+ if result.any?
403
+ entity = result.first[:object]
404
+ puts " Found in: #{result.first[:schema]}"
405
+ puts " Attributes: #{entity.attributes.map(&:id).join(', ')}"
406
+ end
407
+ ----
408
+
409
+ **Output**:
410
+ [source]
411
+ ----
412
+ All entities:
413
+ base_schema.person
414
+ base_schema.organization
415
+ product_schema.product
416
+ product_schema.product_category
417
+
418
+ Entities starting with 'product':
419
+ product_schema.product
420
+ product_schema.product_category
421
+
422
+ Finding 'product_category':
423
+ Found in: product_schema
424
+ Attributes: category_name, products
425
+ ----
426
+
427
+ === Step 8: Validate Packages
428
+
429
+ ==== Validation with CLI
430
+
431
+ [source,bash]
432
+ ----
433
+ # Basic validation
434
+ expressir package validate catalog.ler
435
+
436
+ # Strict validation with checks
437
+ expressir package validate catalog.ler --strict --check-interfaces --detailed
438
+ ----
439
+
440
+ ==== Validation with Ruby API
441
+
442
+ Create `validate_package.rb`:
443
+
444
+ [source,ruby]
445
+ ----
446
+ require 'expressir'
447
+
448
+ # Load package
449
+ repo = Expressir::Model::Repository.from_package('catalog.ler')
450
+
451
+ # Validate
452
+ validation = repo.validate(strict: false)
453
+
454
+ if validation[:valid?]
455
+ puts "✓ Package is valid"
456
+ puts " Total schemas: #{validation[:total_schemas]}"
457
+ puts " Valid schemas: #{validation[:valid_schemas]}"
458
+ else
459
+ puts "✗ Validation failed"
460
+ validation[:errors].each do |error|
461
+ puts " Error: #{error[:message]}"
462
+ end
463
+ end
464
+
465
+ # Check warnings
466
+ if validation[:warnings]&.any?
467
+ puts "\nWarnings:"
468
+ validation[:warnings].each do |warning|
469
+ puts " - #{warning[:message]}"
470
+ end
471
+ end
472
+ ----
473
+
474
+ === Step 9: Package Statistics
475
+
476
+ ==== Get Detailed Statistics
477
+
478
+ Create `package_stats.rb`:
479
+
480
+ [source,ruby]
481
+ ----
482
+ require 'expressir'
483
+
484
+ repo = Expressir::Model::Repository.from_package('catalog.ler')
485
+ stats = repo.statistics
486
+
487
+ puts "Package Statistics"
488
+ puts "=" * 60
489
+
490
+ puts "\nElement counts:"
491
+ puts " Schemas: #{stats[:total_schemas]}"
492
+ puts " Entities: #{stats[:total_entities]}"
493
+ puts " Types: #{stats[:total_types]}"
494
+ puts " Functions: #{stats[:total_functions]}"
495
+ puts " Rules: #{stats[:total_rules]}"
496
+ puts " Procedures: #{stats[:total_procedures]}"
497
+
498
+ if stats[:types_by_category]
499
+ puts "\nTypes by category:"
500
+ stats[:types_by_category].each do |category, count|
501
+ puts " #{category}: #{count}"
502
+ end
503
+ end
504
+
505
+ if stats[:entities_by_schema]
506
+ puts "\nEntities per schema:"
507
+ stats[:entities_by_schema].each do |schema, count|
508
+ puts " #{schema}: #{count} entities"
509
+ end
510
+ end
511
+
512
+ if stats[:interfaces]
513
+ puts "\nInterface usage:"
514
+ puts " USE FROM: #{stats[:interfaces][:use_from]}"
515
+ puts " REFERENCE FROM: #{stats[:interfaces][:reference_from]}"
516
+ end
517
+ ----
518
+
519
+ === Step 10: Build from Schema Manifest
520
+
521
+ ==== Create Schema Manifest
522
+
523
+ Create `schemas.yml`:
524
+
525
+ [source,yaml]
526
+ ----
527
+ schemas:
528
+ - path: base_schema.exp
529
+ id: base_schema
530
+ - path: product_schema.exp
531
+ id: product_schema
532
+ ----
533
+
534
+ ==== Build Package from Manifest
535
+
536
+ [source,bash]
537
+ ----
538
+ # Build from manifest
539
+ expressir package build-from-manifest schemas.yml manifest_catalog.ler \
540
+ --name "Manifest Catalog" \
541
+ --version "1.0.0" \
542
+ --validate
543
+ ----
544
+
545
+ ==== Programmatic Build from Manifest
546
+
547
+ Create `build_from_manifest.rb`:
548
+
549
+ [source,ruby]
550
+ ----
551
+ require 'expressir'
552
+
553
+ # Load manifest
554
+ manifest = Expressir::SchemaManifest.from_file('schemas.yml')
555
+
556
+ # Get file paths
557
+ files = manifest.schemas.map(&:path)
558
+
559
+ puts "Building package from #{files.size} schemas..."
560
+
561
+ # Parse all files
562
+ repo = Expressir::Express::Parser.from_files(files) do |filename, schemas, error|
563
+ if error
564
+ puts " ✗ Error: #{filename}"
565
+ else
566
+ puts " ✓ Loaded: #{filename}"
567
+ end
568
+ end
569
+
570
+ # Export to package
571
+ repo.export_to_package(
572
+ 'programmatic.ler',
573
+ name: 'Programmatic Catalog',
574
+ version: '1.0.0',
575
+ express_mode: 'include_all',
576
+ resolution_mode: 'resolved',
577
+ serialization_format: 'marshal'
578
+ )
579
+
580
+ puts "\n✓ Package created: programmatic.ler"
581
+ ----
582
+
583
+ === Step 11: Package Version Comparison
584
+
585
+ Compare different package configurations.
586
+
587
+ ==== Benchmark Package Performance
588
+
589
+ Create `benchmark_packages.rb`:
590
+
591
+ [source,ruby]
592
+ ----
593
+ require 'expressir'
594
+ require 'benchmark'
595
+
596
+ formats = {
597
+ 'marshal' => 'marshal_catalog.ler',
598
+ 'yaml' => 'yaml_catalog.ler',
599
+ 'json' => 'json_catalog.ler'
600
+ }
601
+
602
+ puts "Package Loading Benchmark"
603
+ puts "=" * 60
604
+
605
+ formats.each do |format, file|
606
+ next unless File.exist?(file)
607
+
608
+ time = Benchmark.realtime do
609
+ repo = Expressir::Model::Repository.from_package(file)
610
+ end
611
+
612
+ size = File.size(file) / 1024.0 # KB
613
+
614
+ puts "\n#{format.upcase} format:"
615
+ puts " Load time: #{(time * 1000).round(2)}ms"
616
+ puts " File size: #{size.round(2)} KB"
617
+ end
618
+ ----
619
+
620
+ === Step 12: Practice Exercises
621
+
622
+ ==== Exercise 1: Multi-Format Packages
623
+
624
+ Create three versions of the same package:
625
+ * Production (marshal, resolved)
626
+ * Development (yaml, resolved)
627
+ * Minimal (json, bare)
628
+
629
+ Compare file sizes and loading times.
630
+
631
+ ==== Exercise 2: Large Package
632
+
633
+ Create a package with at least 10 schemas and 50+ entities.
634
+ Measure:
635
+ * Parsing time
636
+ * Package creation time
637
+ * Package loading time
638
+ * Query performance
639
+
640
+ ==== Exercise 3: Package Distribution
641
+
642
+ Create a package that:
643
+ * Includes metadata (name, version, description)
644
+ * Uses portable format (JSON)
645
+ * Validates successfully
646
+ * Can be loaded on different systems
647
+
648
+ === Common Issues and Solutions
649
+
650
+ ==== "Package file not found"
651
+
652
+ **Problem**: Can't load package
653
+
654
+ **Solution**:
655
+ [source,ruby]
656
+ ----
657
+ # Check file exists
658
+ unless File.exist?('catalog.ler')
659
+ puts "Error: Package file not found"
660
+ exit 1
661
+ end
662
+
663
+ repo = Expressir::Model::Repository.from_package('catalog.ler')
664
+ ----
665
+
666
+ ==== "Invalid package format"
667
+
668
+ **Problem**: Corrupted or incompatible package
669
+
670
+ **Solution**:
671
+ [source,bash]
672
+ ----
673
+ # Rebuild package with validation
674
+ expressir package build schema.exp output.ler --validate
675
+ ----
676
+
677
+ ==== Large Package Performance
678
+
679
+ **Problem**: Package too large or slow to load
680
+
681
+ **Solutions**:
682
+ * Use marshal format (fastest)
683
+ * Enable compression
684
+ * Split into multiple packages
685
+ * Use bare resolution mode for less critical packages
686
+
687
+ === Best Practices
688
+
689
+ **Development**::
690
+ * Use YAML format for readability
691
+ * Include original EXPRESS files
692
+ * Enable validation
693
+ * Keep packages small for iteration
694
+
695
+ **Production**::
696
+ * Use marshal format for speed
697
+ * Pre-resolve all references
698
+ * Validate before deployment
699
+ * Version your packages
700
+
701
+ **Distribution**::
702
+ * Use JSON format for compatibility
703
+ * Include comprehensive metadata
704
+ * Document dependencies
705
+ * Provide examples
706
+
707
+ === Next Steps
708
+
709
+ Congratulations! You can now create and use LER packages.
710
+
711
+ **Continue learning**:
712
+
713
+ * link:querying-schemas.html[Querying Schemas] - Advanced search techniques
714
+ * link:liquid-templates.html[Liquid Templates] - Generate documentation
715
+ * link:../pages/ler-packages.html[LER Packages] - Complete reference
716
+
717
+ **Read more**:
718
+
719
+ * link:../guides/ler/[LER Guides] - Advanced LER usage
720
+ * link:../guides/ruby-api/[Ruby API Guides] - Programmatic access
721
+ * link:../guides/cli/[CLI Guides] - Command-line tools
722
+
723
+ === Summary
724
+
725
+ In this tutorial, you learned to:
726
+
727
+ * ✅ Understand LER package benefits
728
+ * ✅ Create packages with different configurations
729
+ * ✅ Optimize packages for various use cases
730
+ * ✅ Load and use packages efficiently
731
+ * ✅ Validate package integrity
732
+ * ✅ Query package contents
733
+ * ✅ Compare package formats
734
+
735
+ You're now ready to distribute EXPRESS schemas efficiently with LER packages!