leptris 1.9.14 → 1.9.15

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7fd93de4896102e873db7213b16769cae179f5e5bee367ce8fda30c9e8da3066
4
- data.tar.gz: ac9c5c315ed5ddf461787d43993e95d41d914fe5ebbfbf18948223081c51cc89
3
+ metadata.gz: c1b73d7abca12056f163aed086825140416384075955e593f11191156db475fc
4
+ data.tar.gz: ead9075339cfd0736ca79cbede18612702f4632c95d9d90a512f67b3e4c32ec7
5
5
  SHA512:
6
- metadata.gz: 84004c1a067858c776616e4a1c08ec716a9272ff5879044fb683d6ff163c584ab397993b46bb365272fba05a9925d868dd9fbec83be0c360b6d94abedacdf2cf
7
- data.tar.gz: e8da7f674dcbc79c4c93d27aefb589588e91e11bc370edbc1dbba935aadc821dd241a82a1820725fff5d25338b6de6df93fbd12771c646081bd5c73a846a8838
6
+ metadata.gz: 22ec81a95a094913096d9c0749c42a64274f7af9225c4128b51529c8160f6480d3f23476b548f7c766202be9744dee9a830eaa715dbeea77a42e4d374f61b6e5
7
+ data.tar.gz: 5e5408837f3ca2b4b54e4069a36798000b67d87fee9ed7021927b4e6c8b95d6a04a9f9d770fcd786763569d700182f87fc5b7df54c14462391c0420f69d108ed
data/CHANGELOG.md CHANGED
@@ -5,6 +5,23 @@ All notable changes to Leptris will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.9.15] - 2026-08-27
9
+
10
+ ### Changed
11
+
12
+ - **`Element#[]` serves bare names from the versioned attributes
13
+ hash on every document kind** (writable included): materializes
14
+ on demand, invalidates through the mutation gate. Qualified names
15
+ (with a colon) still route to the engine — they resolve through
16
+ in-scope declarations where the written prefix never matters,
17
+ which a written-name-keyed hash cannot answer. Writable
18
+ attribute loops reach readonly parity: 0.196 s -> 0.101 s (2x);
19
+ the readonly special-case branch is deleted. The qualified/bare
20
+ split is spec-pinned (cross-prefix match, undeclared-prefix nil).
21
+ - **`first_element_child` memoizes** with version invalidation
22
+ (structural mutations bump): 0.058 s -> 0.015 s (4x) on the
23
+ repeat loop.
24
+
8
25
  ## [1.9.14] - 2026-08-27
9
26
 
10
27
  ### Changed
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Leptris
4
- VERSION = "1.9.14"
4
+ VERSION = "1.9.15"
5
5
  end
@@ -35,16 +35,20 @@ class Leptris::XML::Element < Leptris::XML::Node
35
35
  end
36
36
 
37
37
  def [](key)
38
- # Readonly: the attributes hash cannot go stale (ADR 0003) and
39
- # materializes on demand repeated reads become hash lookups,
40
- # with no dispatch and no lifetime guard (a hash read cannot
41
- # use-after-free).
42
- if readonly_document?
43
- cached = attributes[key.to_s]
38
+ # BARE names serve from the versioned attributes hash (written
39
+ # name == the only legal key for a no-namespace attribute);
40
+ # materializes on demand, invalidates through the mutation gate
41
+ # (ADR 0003's 1.9.14 extension); a hash read cannot
42
+ # use-after-free. QUALIFIED names (with a colon) go to the
43
+ # engine: they resolve through in-scope declarations, where the
44
+ # written prefix never matters — the hash cannot answer them.
45
+ name = key.to_s
46
+ if @document && !name.include?(":")
47
+ cached = attributes[name]
44
48
  return cached.nil? ? nil : cached.value
45
49
  end
46
50
  ensure_alive!
47
- Leptris::XML::FFI.leptris_element_attribute(@c_ptr, key.to_s)
51
+ Leptris::XML::FFI.leptris_element_attribute(@c_ptr, name)
48
52
  end
49
53
  alias_method :attr, :[]
50
54
  alias_method :get_attribute, :[]
@@ -179,14 +179,23 @@ class Leptris::XML::Node
179
179
  alias_method :previous, :previous_sibling
180
180
 
181
181
  def first_element_child
182
+ return @first_element_child if memo_hit?(@first_element_child_version)
182
183
  ensure_alive!
183
184
  ptr = Leptris::XML::FFI.leptris_node_first_child(@c_ptr)
185
+ result = nil
184
186
  until ptr.nil? || ptr.null?
185
187
  node = Leptris::XML::Node.wrap(ptr, @document, parent: as_element_or_self)
186
- return node if node.element?
188
+ if node.element?
189
+ result = node
190
+ break
191
+ end
187
192
  ptr = Leptris::XML::FFI.leptris_node_next_sibling(ptr)
188
193
  end
189
- nil
194
+ if @document
195
+ @first_element_child = result
196
+ @first_element_child_version = @document.version
197
+ end
198
+ result
190
199
  end
191
200
 
192
201
  def last_element_child
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: leptris
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.14
4
+ version: 1.9.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.